diff --git a/awt/Android.mk b/awt/Android.mk
deleted file mode 100644
index 213c6ce..0000000
--- a/awt/Android.mk
+++ /dev/null
@@ -1,31 +0,0 @@
-#
-# 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
deleted file mode 100644
index 9a8ae02..0000000
--- a/awt/com/android/internal/awt/AndroidGraphics2D.java
+++ /dev/null
@@ -1,1354 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 0c888cd..0000000
--- a/awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * 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
deleted file mode 100644
index ca255b5..0000000
--- a/awt/com/android/internal/awt/AndroidGraphicsFactory.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 81b2e1a..0000000
--- a/awt/com/android/internal/awt/AndroidImageDecoder.java
+++ /dev/null
@@ -1,274 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 423b534..0000000
--- a/awt/com/android/internal/awt/AndroidJavaBlitter.java
+++ /dev/null
@@ -1,536 +0,0 @@
-/*
- * 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
deleted file mode 100644
index fc30614..0000000
--- a/awt/com/android/internal/awt/AndroidNativeEventQueue.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 1609d11..0000000
--- a/awt/com/android/internal/awt/AndroidWTK.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 6e667b2..0000000
--- a/awt/com/android/internal/awt/AwtFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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
deleted file mode 100644
index 92185fd..0000000
--- a/awt/com/android/internal/awt/ImageOutputStreamWrapper.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
deleted file mode 100644
index a8dc83a..0000000
--- a/awt/java/awt/AWTEvent.java
+++ /dev/null
@@ -1,681 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 class AWTEvent is the base class for all AWT events. This class
- * and its subclasses supersede the original java.awt.Event class.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 6590b73..0000000
--- a/awt/java/awt/AWTException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index f01f6f0..0000000
--- a/awt/java/awt/AWTKeyStroke.java
+++ /dev/null
@@ -1,712 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- *  
- *  @since Android 1.0
- */
-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, false otherwise.
-     */
-    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 realized value.
-     */
-    protected AWTKeyStroke() {
-        this(KeyEvent.CHAR_UNDEFINED, KeyEvent.VK_UNDEFINED, 0, false);
-    }
-
-    /**
-     * Returns the unique number value for AWTKeyStroke object.
-     * 
-     * @return the integer 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 integer value which contains modifiers.
-     */
-    public final int getModifiers() {
-        return modifiers;
-    }
-
-    /**
-     * Compares this AWTKeyStroke object to the specified object.
-     * 
-     * @param anObject
-     *            the specified AWTKeyStroke object to compare with this
-     *            instance.
-     * @return true if objects are identical, false otherwise.
-     */
-    @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.
-     * @param onKeyRelease
-     *            the value which represents whether this AWTKeyStroke shall
-     *            represents a key release.
-     * @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);
-    }
-
-    /**
-     * Returns true if the key event is associated with the AWTKeyStroke is
-     * KEY_RELEASED, false otherwise.
-     * 
-     * @return true, if if the key event associated with the AWTKeyStroke is
-     *         KEY_RELEASED, false otherwise.
-     */
-    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
deleted file mode 100644
index 3327d63..0000000
--- a/awt/java/awt/AWTListenerList.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 4bd8357..0000000
--- a/awt/java/awt/AWTPermission.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 7044623..0000000
--- a/awt/java/awt/ActiveEvent.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index baf80f7..0000000
--- a/awt/java/awt/Adjustable.java
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8389eb4..0000000
--- a/awt/java/awt/AlphaComposite.java
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 the 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 the 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
deleted file mode 100644
index 2457815..0000000
--- a/awt/java/awt/BasicStroke.java
+++ /dev/null
@@ -1,2443 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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>
- * </p>
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index cd5fe7b..0000000
--- a/awt/java/awt/BufferCapabilities.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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
deleted file mode 100644
index 93c532d..0000000
--- a/awt/java/awt/Color.java
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *            the 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 alpha 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
-     *            the String which represents an opaque color as a 24-bit
-     *            integer.
-     * @return the Color object from the given String.
-     * @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 value.
-         */
-        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
deleted file mode 100644
index c52a9f4..0000000
--- a/awt/java/awt/Component.java
+++ /dev/null
@@ -1,6020 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * 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).
- * 
- * @since Android 1.0
- */
-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>.
-     * 
-     * @since Android 1.0
-     */
-    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.
-     * 
-     * @since Android 1.0
-     */
-    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 overridden 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;
-    }
-
-    /**
-     * Handles the event. Use ActionListener instead of this.
-     * 
-     * @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 the 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 the 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
deleted file mode 100644
index f4e8ffb..0000000
--- a/awt/java/awt/ComponentBehavior.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 5acc11a..0000000
--- a/awt/java/awt/ComponentOrientation.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 writing 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").
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index d1730fe..0000000
--- a/awt/java/awt/Composite.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 795640d..0000000
--- a/awt/java/awt/CompositeContext.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 0a0cc84..0000000
--- a/awt/java/awt/Cursor.java
+++ /dev/null
@@ -1,427 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 overrides the 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
deleted file mode 100644
index 6777962..0000000
--- a/awt/java/awt/Dimension.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index d457af4..0000000
--- a/awt/java/awt/Dispatcher.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 8021010..0000000
--- a/awt/java/awt/DisplayMode.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 contains the bit depth, height, width and refresh rate
- * of a GraphicsDevice.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 226a61f..0000000
--- a/awt/java/awt/Event.java
+++ /dev/null
@@ -1,596 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 iconify 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 deiconify 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
-     * unselected.
-     */
-    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 distance by which the event's x coordinate is increased.
-     * @param 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
deleted file mode 100644
index 442c8a2..0000000
--- a/awt/java/awt/EventDispatchThread.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 126a593..0000000
--- a/awt/java/awt/EventQueue.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 an error occurred while 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
deleted file mode 100644
index ffc7c46..0000000
--- a/awt/java/awt/EventQueueCore.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 4ed9343..0000000
--- a/awt/java/awt/Font.java
+++ /dev/null
@@ -1,1541 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.luni.util.NotImplementedException;
-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 glyph,
- * 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.
- * 
- * @since Android 1.0
- */
-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.
-     * @throws NotImplementedException
-     *             if this method is not implemented by a subclass.
-     */
-    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);
-    }
-
-    /**
-     * Performs 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 such 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
deleted file mode 100644
index 806711a..0000000
--- a/awt/java/awt/FontFormatException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 9082626..0000000
--- a/awt/java/awt/FontMetrics.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * </p>
- * 
- * @since Android 1.0
- */
-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 a FontRenderContext instance 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
deleted file mode 100644
index 3b32ef5..0000000
--- a/awt/java/awt/GradientPaint.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
-     *            the 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
deleted file mode 100644
index 74575f5..0000000
--- a/awt/java/awt/GradientPaintContext.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 2d6e79f..0000000
--- a/awt/java/awt/Graphics.java
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 beginning 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.
- * 
- * @since Android 1.0
- */
-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 dimensions.
-     * 
-     * @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 highlighted 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 highlighted 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, false otherwise.
-     */
-    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.
-     * 
-     * @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 dimensions
-     * (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 negative 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, otherwise 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, false
-     *         otherwise.
-     */
-    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, otherwise 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, otherwise
-     *         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, otherwise 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, otherwise
-     *         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, otherwise 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, otherwise
-     *         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, otherwise 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, false
-     *         otherwise.
-     */
-    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, otherwise 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, false
-     *         otherwise.
-     */
-    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 outline 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 first 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 first 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 dimensions (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
-     *            the Shape object which represents 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
deleted file mode 100644
index 04a7319..0000000
--- a/awt/java/awt/Graphics2D.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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 perform
- * 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>
- * 
- * @since Android 1.0
- */
-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
-     * preferences 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 outline 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 whether 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, false otherwise.
-     */
-    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 highlighted 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
deleted file mode 100644
index d59e896..0000000
--- a/awt/java/awt/GraphicsConfiguration.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 9eda4e0..0000000
--- a/awt/java/awt/GraphicsDevice.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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, false
-     *         otherwise.
-     */
-    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
deleted file mode 100644
index d527417..0000000
--- a/awt/java/awt/GraphicsEnvironment.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 objects 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
deleted file mode 100644
index ec111f1..0000000
--- a/awt/java/awt/HeadlessException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 306393f..0000000
--- a/awt/java/awt/HeadlessGraphicsEnvironment.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index c64a85a..0000000
--- a/awt/java/awt/HeadlessToolkit.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index bed1729..0000000
--- a/awt/java/awt/IllegalComponentStateException.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 7ae3ed8..0000000
--- a/awt/java/awt/Image.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 algorithm.
-     * 
-     * @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 reconstructed 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
deleted file mode 100644
index c6d5946..0000000
--- a/awt/java/awt/ImageCapabilities.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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);
-    }
-
-    /**
-     * Returns 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
deleted file mode 100644
index 04f198c..0000000
--- a/awt/java/awt/Insets.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 212cf70..0000000
--- a/awt/java/awt/ItemSelectable.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 9c1b120..0000000
--- a/awt/java/awt/MenuComponent.java
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * The MenuComponent abstract class is the superclass for menu components. Menu
- * components receive and process AWT events.
- * 
- * @since Android 1.0
- */
-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.
-     * @throws NotImplementedException
-     *             if this method is not implemented by a subclass.
-     * @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 current 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 item.
-     * @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
deleted file mode 100644
index e509a1b..0000000
--- a/awt/java/awt/MenuContainer.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 32a5912..0000000
--- a/awt/java/awt/ModalContext.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index df48f9d..0000000
--- a/awt/java/awt/MouseDispatcher.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index dfea3a7..0000000
--- a/awt/java/awt/Paint.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 966b6ca..0000000
--- a/awt/java/awt/PaintContext.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8ec4241..0000000
--- a/awt/java/awt/Point.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 location 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, false otherwise.
-     * @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
deleted file mode 100644
index de31eb9..0000000
--- a/awt/java/awt/Polygon.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 segment 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, false
-     *         otherwise.
-     * @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, false
-     *         otherwise.
-     */
-    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, false otherwise.
-     * @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 height
-     *            the height of rectangle as a double.
-     * @return true, if the specified rectangle lies inside the Polygon, false
-     *         otherwise.
-     * @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 height
-     *            the height of rectangle as a double.
-     * @return true, if the specified rectangle intersects the interior of the
-     *         Polygon, false otherwise.
-     * @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, false
-     *         otherwise.
-     * @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, false
-     *         otherwise.
-     */
-    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, false
-     *         otherwise.
-     * @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,
-     *         false otherwise.
-     * @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
deleted file mode 100644
index d8ebb3a..0000000
--- a/awt/java/awt/Rectangle.java
+++ /dev/null
@@ -1,723 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 dimension 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 Dimension object.
-     * 
-     * @return a Dimension 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, false otherwise.
-     */
-    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, false otherwise.
-     */
-    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, false otherwise.
-     */
-    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, false otherwise.
-     */
-    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 integer 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, false otherwise.
-     * @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
deleted file mode 100644
index acf6fa1..0000000
--- a/awt/java/awt/RenderingHints.java
+++ /dev/null
@@ -1,606 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 compared.
-     * @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.
-     * 
-     * @since Android 1.0
-     */
-    public abstract static class Key {
-
-        /** The key. */
-        private final int key;
-
-        /**
-         * Instantiates a new key with unique integer 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 compared.
-         * @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 integer unique key with which this Key object has been
-         * instantiated.
-         * 
-         * @return the integer 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 implementation.
-         * 
-         * @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
deleted file mode 100644
index 59bc623..0000000
--- a/awt/java/awt/Shape.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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, false
-     *         otherwise.
-     */
-    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, false
-     *         otherwise.
-     */
-    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, false
-     *         otherwise.
-     */
-    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, false
-     *         otherwise.
-     */
-    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, false otherwise.
-     */
-    public boolean intersects(double x, double y, double w, double h);
-
-    /**
-     * Checks whether or not the interior of rectangle 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
deleted file mode 100644
index 6d17a23..0000000
--- a/awt/java/awt/Stroke.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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)
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e38d524..0000000
--- a/awt/java/awt/Toolkit.java
+++ /dev/null
@@ -1,1444 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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 default 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();
-    }
-
-    /**
-     * Initiates 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 beginning 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 preferred cursor width.
-     * @param prefHeight
-     *            the preferred 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 otherwise.
-     * @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
-     *            the 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
-     *            the 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
-     *            the 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
deleted file mode 100644
index 5015aef..0000000
--- a/awt/java/awt/ToolkitImpl.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 44a1e7f..0000000
--- a/awt/java/awt/Transparency.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 18b9a7e..0000000
--- a/awt/java/awt/color/CMMException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 occurs.
- * 
- * @since Android 1.0
- */
-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 detail message of the exception.
-     */
-    public CMMException (String s) {
-        super (s);
-    }
-}
diff --git a/awt/java/awt/color/ColorSpace.java b/awt/java/awt/color/ColorSpace.java
deleted file mode 100644
index 44c491b..0000000
--- a/awt/java/awt/color/ColorSpace.java
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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$
-    }
-
-    /**
-     * Performs the transformation of 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);
-
-    /**
-     * Performs the transformation of 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 the transformation of a color from the RGB color space into this
-     * ColorSpace.
-     * 
-     * @param rgbvalue
-     *            the float array representing a color in the RGB color space.
-     * @return the float array with the transformed color components.
-     */
-    public abstract float[] fromRGB(float[] rgbvalue);
-
-    /**
-     * Performs the transformation of a color from the CS_CIEXYZ color space
-     * into this ColorSpace.
-     * 
-     * @param colorvalue
-     *            the float array representing a color in the CS_CIEXYZ color
-     *            space.
-     * @return the float array with the transformed color components.
-     */
-    public abstract float[] fromCIEXYZ(float[] colorvalue);
-
-    /**
-     * Gets the minimum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the minimum value.
-     * @return the minimum 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 to determine the maximum value.
-     * @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
deleted file mode 100644
index 5b4d7e9..0000000
--- a/awt/java/awt/color/ICC_ColorSpace.java
+++ /dev/null
@@ -1,468 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.*;
-
-/**
- * This class implements the abstract class ColorSpace 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>
- * 
- * @since Android 1.0
- */
-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();
-    }
-
-    /**
-     * Gets 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;
-    }
-
-    /**
-     * Performs the transformation of 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.
-     */
-    @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;
-    }
-
-    /**
-     * Performs the transformation of 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.
-     */
-    @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;
-    }
-
-    /**
-     * Performs the transformation of a color from the RGB color space into this
-     * ColorSpace.
-     * 
-     * @param rgbvalue
-     *            the float array representing a color in the RGB color space.
-     * @return the float array with the transformed color components.
-     */
-    @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;
-    }
-
-    /**
-     * Performs the transformation of a color from the CS_CIEXYZ color space
-     * into this ColorSpace.
-     * 
-     * @param xyzvalue
-     *            the float array representing a color in the CS_CIEXYZ color
-     *            space.
-     * @return the float array with the transformed color components.
-     */
-    @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;
-    }
-
-    /**
-     * Gets the minimum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the minimum value.
-     * @return the minimum normalized value of the component.
-     */
-    @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];
-    }
-
-    /**
-     * Gets the maximum normalized color component value for the specified
-     * component.
-     * 
-     * @param component
-     *            the component to determine the maximum value.
-     * @return the maximum normalized value of the 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
deleted file mode 100644
index 8ffee6c..0000000
--- a/awt/java/awt/color/ICC_Profile.java
+++ /dev/null
@@ -1,1477 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 ICC profile with the given data.
-     * 
-     * @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
-     *             if 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$
-
-    }
-
-    /**
-     * Gets 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 the file at the specified path. Path entries can be divided
-     * by a separator character.
-     * 
-     * @param path
-     *            the path to the file.
-     * @param fileName
-     *            the file name.
-     * @return the input stream to read the file.
-     */
-    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 occurred while reading the file or
-     *             the file does not 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 integer value 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
deleted file mode 100644
index f748101..0000000
--- a/awt/java/awt/color/ICC_ProfileGray.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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]
- * 
- * @since Android 1.0
- */
-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 the short array of the TRC.
-     */
-    public short[] getTRC() {
-        return super.getTRC(icSigGrayTRCTag);
-    }
-
-    /**
-     * Gets the media white point.
-     * 
-     * @return the media white point
-     */
-    @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
deleted file mode 100644
index 9c6010f..0000000
--- a/awt/java/awt/color/ICC_ProfileRGB.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-public class ICC_ProfileRGB extends ICC_Profile {
-    
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 8505067385152579334L;
-
-    /**
-     * Instantiates a new RGB ICC_Profile.
-     * 
-     * @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$
-
-    /**
-     * Gets the TRC.
-     * 
-     * @param component
-     *            the tag signature.
-     * @return the TRC value.
-     */
-    @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);
-    }
-
-    /**
-     * Gets the gamma.
-     * 
-     * @param component
-     *            the tag signature.
-     * @return the gamma value.
-     */
-    @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 the 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;
-    }
-
-    /**
-     * Gets the media white point.
-     * 
-     * @return the media white point.
-     */
-    @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
deleted file mode 100644
index bc04c8a..0000000
--- a/awt/java/awt/color/ICC_ProfileStub.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 335f314..0000000
--- a/awt/java/awt/color/ProfileDataException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 of the exception.
-     */
-    public ProfileDataException(String s) {
-        super(s);
-    }
-
-}
-
diff --git a/awt/java/awt/color/package.html b/awt/java/awt/color/package.html
deleted file mode 100644
index 609d963..0000000
--- a/awt/java/awt/color/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes representing color spaces and profiles based on the International Color Consortium (ICC) Profile Format Specification. 
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/event/AWTEventListener.java b/awt/java/awt/event/AWTEventListener.java
deleted file mode 100644
index 76293b3..0000000
--- a/awt/java/awt/event/AWTEventListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 3edc41f3..0000000
--- a/awt/java/awt/event/AWTEventListenerProxy.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e882e0d..0000000
--- a/awt/java/awt/event/ActionEvent.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index a6eee7a..0000000
--- a/awt/java/awt/event/ActionListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index be2d6c4..0000000
--- a/awt/java/awt/event/AdjustmentEvent.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 5f6a724..0000000
--- a/awt/java/awt/event/AdjustmentListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index c42235f..0000000
--- a/awt/java/awt/event/ComponentAdapter.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 760d3ab..0000000
--- a/awt/java/awt/event/ComponentEvent.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index a5adba2..0000000
--- a/awt/java/awt/event/ComponentListener.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 44983c7..0000000
--- a/awt/java/awt/event/ContainerAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 372c9e4..0000000
--- a/awt/java/awt/event/ContainerEvent.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 517859e..0000000
--- a/awt/java/awt/event/ContainerListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 3a3e37f..0000000
--- a/awt/java/awt/event/FocusAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 4a18689..0000000
--- a/awt/java/awt/event/FocusEvent.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 6bbbd00..0000000
--- a/awt/java/awt/event/FocusListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index bbfe8ff..0000000
--- a/awt/java/awt/event/HierarchyBoundsAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 3e8f2e7..0000000
--- a/awt/java/awt/event/HierarchyBoundsListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index c1d22f4..0000000
--- a/awt/java/awt/event/HierarchyEvent.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index ff3d9bc..0000000
--- a/awt/java/awt/event/HierarchyListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 343b7a3..0000000
--- a/awt/java/awt/event/InputEvent.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index be001a5..0000000
--- a/awt/java/awt/event/InputMethodEvent.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 85eaa7e..0000000
--- a/awt/java/awt/event/InputMethodListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 58e3b72..0000000
--- a/awt/java/awt/event/InvocationEvent.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 09908f2..0000000
--- a/awt/java/awt/event/ItemEvent.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8dec673..0000000
--- a/awt/java/awt/event/ItemListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index a96cca8..0000000
--- a/awt/java/awt/event/KeyAdapter.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8627f70..0000000
--- a/awt/java/awt/event/KeyEvent.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index ec144df..0000000
--- a/awt/java/awt/event/KeyListener.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index dc19173..0000000
--- a/awt/java/awt/event/MouseAdapter.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2b1fa8b..0000000
--- a/awt/java/awt/event/MouseEvent.java
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 95879b9..0000000
--- a/awt/java/awt/event/MouseListener.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1ecd0d5..0000000
--- a/awt/java/awt/event/MouseMotionAdapter.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e1313c3..0000000
--- a/awt/java/awt/event/MouseMotionListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index a3ed424..0000000
--- a/awt/java/awt/event/MouseWheelEvent.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2d6a982..0000000
--- a/awt/java/awt/event/MouseWheelListener.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 22ac090..0000000
--- a/awt/java/awt/event/PaintEvent.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2a690ad..0000000
--- a/awt/java/awt/event/TextEvent.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 05757c4..0000000
--- a/awt/java/awt/event/TextListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 970aa8d..0000000
--- a/awt/java/awt/event/WindowAdapter.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 474d2ac..0000000
--- a/awt/java/awt/event/WindowEvent.java
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 528459f..0000000
--- a/awt/java/awt/event/WindowFocusListener.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 31bd547..0000000
--- a/awt/java/awt/event/WindowListener.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index ba14d9e..0000000
--- a/awt/java/awt/event/WindowStateListener.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index d7de00f..0000000
--- a/awt/java/awt/font/FontRenderContext.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index b03de0a..0000000
--- a/awt/java/awt/font/GlyphJustificationInfo.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * </p>
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2871722..0000000
--- a/awt/java/awt/font/GlyphMetrics.java
+++ /dev/null
@@ -1,266 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index a72b774..0000000
--- a/awt/java/awt/font/GlyphVector.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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>
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8480e0f..0000000
--- a/awt/java/awt/font/GraphicAttribute.java
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index d6d4758..0000000
--- a/awt/java/awt/font/ImageGraphicAttribute.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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);
-    }
-
-    @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);
-    }
-
-    @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
deleted file mode 100644
index 4800093..0000000
--- a/awt/java/awt/font/LineBreakMeasurer.java
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 position 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 the current position of this LineBreakMeasurer
-     */
-    public int getPosition() {
-        return position;
-    }
-
-    /**
-     * Inserts a character at the specified position in the text, updates this
-     * LineBreakMeasurer object.
-     * 
-     * @param newText
-     *            the new text.
-     * @param pos
-     *            the position 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 within 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
deleted file mode 100644
index 4b03e5d..0000000
--- a/awt/java/awt/font/LineMetrics.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index d264f24..0000000
--- a/awt/java/awt/font/MultipleMaster.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index db66911..0000000
--- a/awt/java/awt/font/OpenType.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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>.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 182bffd..0000000
--- a/awt/java/awt/font/ShapeGraphicAttribute.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 6460eba..0000000
--- a/awt/java/awt/font/TextHitInfo.java
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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").
- * 
- * @since Android 1.0
- */
-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;
-    }
-
-    /**
-     * Returns the textual string representation of this TextHitInfo instance.
-     * 
-     * @return the string representation.
-     */
-    @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;
-    }
-
-    /**
-     * Returns the hash code value of this TextHitInfo instance.
-     * 
-     * @return the hash code value.
-     */
-    @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
deleted file mode 100644
index cc6f0ba..0000000
--- a/awt/java/awt/font/TextLayout.java
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *            corresponding to the given coordinates within the text.
-     * @return the information about the character at the specified position.
-     */
-    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 corresponding
-     *            to the given coordinates within the text.
-     * @return the information about the character at the specified position.
-     */
-    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
deleted file mode 100644
index 9741f59..0000000
--- a/awt/java/awt/font/TextMeasurer.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index ff2caa2..0000000
--- a/awt/java/awt/font/TransformAttribute.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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/font/package.html b/awt/java/awt/font/package.html
deleted file mode 100644
index 788dcc0..0000000
--- a/awt/java/awt/font/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes to support the representation of different types of fonts for example TrueType fonts.
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/geom/AffineTransform.java b/awt/java/awt/geom/AffineTransform.java
deleted file mode 100644
index 8a6938c..0000000
--- a/awt/java/awt/geom/AffineTransform.java
+++ /dev/null
@@ -1,1267 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 collinearity 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.
- * 
- * @since Android 1.0
- */
-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 stream.
-     */
-    private void writeObject(java.io.ObjectOutputStream stream) throws IOException {
-        stream.defaultWriteObject();
-    }
-
-    /**
-     * Read the AffineTransform object from the input stream.
-     * 
-     * @param stream
-     *            - the input stream.
-     * @throws IOException
-     *             - if there are I/O errors while reading from the input
-     *             stream.
-     * @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
deleted file mode 100644
index 56f5cd3..0000000
--- a/awt/java/awt/geom/Arc2D.java
+++ /dev/null
@@ -1,1157 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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).
- * 
- * @since Android 1.0
- */
-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
-     * @since Android 1.0
-     */
-    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
-     * @since Android 1.0
-     */
-    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 width 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 width 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 width 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 tangent lines (with
-     *            p2).
-     * @param p2
-     *            the point of intersection of the two tangent lines.
-     * @param p3
-     *            a point which determines one of the two tangent 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
deleted file mode 100644
index e6619e3..0000000
--- a/awt/java/awt/geom/Area.java
+++ /dev/null
@@ -1,330 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-import org.apache.harmony.luni.util.NotImplementedException;
-
-/**
- * The Class Area provides a minimal implementation for a generic shape.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1ddedf3..0000000
--- a/awt/java/awt/geom/CubicCurve2D.java
+++ /dev/null
@@ -1,1047 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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>.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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.
-     * 
-     * @since Android 1.0
-     */
-    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 segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new CubicCurve2D.Iterator for given line and
-         * transformation
-         * 
-         * @param c
-         *            the source CubicCurve2D object.
-         * @param t
-         *            the affine transformation object.
-         */
-        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 {@code 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 {@code 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
deleted file mode 100644
index ea081c5..0000000
--- a/awt/java/awt/geom/Dimension2D.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 89fd0d0..0000000
--- a/awt/java/awt/geom/Ellipse2D.java
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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.
-     * 
-     * @since Android 1.0
-     */
-    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 segment index.
-         */
-        int index;
-
-        /**
-         * Constructs a new Ellipse2D.Iterator for given ellipse and
-         * transformation
-         * 
-         * @param e
-         *            the source Ellipse2D object.
-         * @param t
-         *            the affine transformation object.
-         */
-        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
deleted file mode 100644
index 8208f39..0000000
--- a/awt/java/awt/geom/FlatteningPathIterator.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 within the flattening factor of the curve or until
- * the buffer limit is reached.
- * 
- * @since Android 1.0
- */
-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 temporary 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 within
-     * 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 series. 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
deleted file mode 100644
index 0669bc7..0000000
--- a/awt/java/awt/geom/GeneralPath.java
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 750ba29..0000000
--- a/awt/java/awt/geom/IllegalPathStateException.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 incompatible with the desired action, such as performing
- * non-trivial actions on an empty path.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index fcd51b6..0000000
--- a/awt/java/awt/geom/Line2D.java
+++ /dev/null
@@ -1,948 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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.
-     * 
-     * @since Android 1.0
-     */
-    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 segment 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
deleted file mode 100644
index a4e6f0f..0000000
--- a/awt/java/awt/geom/NoninvertibleTransformException.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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).
- * 
- * @since Android 1.0
- */
-public class NoninvertibleTransformException extends java.lang.Exception {
-
-    /**
-     * The Constant serialVersionUID.
-     */
-    private static final long serialVersionUID = 6137225240503990466L;
-
-    /**
-     * Instantiates a new non-invertible 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
deleted file mode 100644
index 2d1c0ff..0000000
--- a/awt/java/awt/geom/PathIterator.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * </p>
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index f7026c8..0000000
--- a/awt/java/awt/geom/Point2D.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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.
-     * 
-     * @since Android 1.0
-     */
-    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
deleted file mode 100644
index 7a86a48..0000000
--- a/awt/java/awt/geom/QuadCurve2D.java
+++ /dev/null
@@ -1,918 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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.
-     * 
-     * @since Android 1.0
-     */
-    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 {@code 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 {@code 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 {code 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 {@code src.length} < srcoff + 6 or if {@code left.length}
-     *             < leftOff + 6 or if {@code 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 {@code 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 {@code eqn.length} < 3 or if {@code 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
deleted file mode 100644
index 8166134..0000000
--- a/awt/java/awt/geom/Rectangle2D.java
+++ /dev/null
@@ -1,824 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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).
-     * 
-     * @since Android 1.0
-     */
-    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).
-     * 
-     * @since Android 1.0
-     */
-    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 Rectangle2D.
-     */
-    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 integer 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 integer 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 that 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
deleted file mode 100644
index 0b0d05c..0000000
--- a/awt/java/awt/geom/RectangularShape.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8fbddd6..0000000
--- a/awt/java/awt/geom/RoundRectangle2D.java
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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.
-     * 
-     * @since Android 1.0
-     */
-    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 arc width of the rounded corners.
-         */
-        public float arcwidth;
-
-        /**
-         * The arc height 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 arc width of the rounded corners.
-         * @param archeight
-         *            the arc height 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 rectangle.
-         * 
-         * @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 arc width of the rounded corners.
-         * @param archeight
-         *            the arc height 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.
-     * 
-     * @since Android 1.0
-     */
-    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 arc width of the rounded corners.
-         */
-        public double arcwidth;
-
-        /**
-         * The arc height 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 arc width of the rounded corners.
-         * @param archeight
-         *            the arc height 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 segment 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 arc width of the rounded corners.
-     * @param arcHeight
-     *            the arc height 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/geom/package.html b/awt/java/awt/geom/package.html
deleted file mode 100644
index e3a236e..0000000
--- a/awt/java/awt/geom/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces related to Java2D shapes and geometry.
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/im/InputContext.java b/awt/java/awt/im/InputContext.java
deleted file mode 100644
index cce5148..0000000
--- a/awt/java/awt/im/InputContext.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 865d47c..0000000
--- a/awt/java/awt/im/InputMethodHighlight.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index b12d397..0000000
--- a/awt/java/awt/im/InputMethodRequests.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 708881e..0000000
--- a/awt/java/awt/im/InputSubset.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 67a8834..0000000
--- a/awt/java/awt/im/spi/InputMethod.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index bfc773c..0000000
--- a/awt/java/awt/im/spi/InputMethodContext.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index c800bc1..0000000
--- a/awt/java/awt/im/spi/InputMethodDescriptor.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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;
-
-/**
- * This class is not supported in Android 1.0. It is merely provided to maintain
- * interface compatibility with desktop Java implementations.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index db25e1a..0000000
--- a/awt/java/awt/image/AffineTransformOp.java
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 bi-cubic 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
deleted file mode 100644
index 7fb138e..0000000
--- a/awt/java/awt/image/AreaAveragingScaleFilter.java
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 transferring 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
-     *            the source pixels X coordinate.
-     * @param y
-     *            the source pixels Y coordinate.
-     * @param w
-     *            the width of the area of the source pixels.
-     * @param h
-     *            the height of the area of the source pixels.
-     * @param model
-     *            the color model of the source pixels.
-     * @param pixels
-     *            the array of source pixels.
-     * @param off
-     *            the offset into the source pixels array.
-     * @param scansize
-     *            the 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
deleted file mode 100644
index 6dffee8..0000000
--- a/awt/java/awt/image/AwtImageBackdoorAccessorImpl.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index da2cc89..0000000
--- a/awt/java/awt/image/BandCombineOp.java
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 0aa30d7..0000000
--- a/awt/java/awt/image/BandedSampleModel.java
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 indices.
-     * @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
deleted file mode 100644
index 3c8779d..0000000
--- a/awt/java/awt/image/BufferStrategy.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 detectable through
- * the capabilities object which can be obtained by the GraphicsConfiguration of
- * the Canvas or Window.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index c9d58d9..0000000
--- a/awt/java/awt/image/BufferedImage.java
+++ /dev/null
@@ -1,952 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     * pre-multiplied 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 pre-multiplied 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 pre-multiplied 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 pre-multiplied 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
-     * color space of the specified area of this BufferedImage. The result array
-     * is composed by the following algorithm:
-     * <p>
-     * pixel = rgbArray[offset + (y-startY)*scansize + (x-startX)]
-     * </p>
-     * 
-     * @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 color
-     * space 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 color space.
-     */
-    public int getRGB(int x, int y) {
-        return cm.getRGB(raster.getDataElements(x, y, null));
-    }
-
-    /**
-     * Returns true if alpha is pre-multiplied, false if alpha is not
-     * pre-multiplied or there is no alpha.
-     * 
-     * @return true if alpha is pre-multiplied, false if alpha is not
-     *         pre-multiplied 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
deleted file mode 100644
index 8b6fcf0..0000000
--- a/awt/java/awt/image/BufferedImageFilter.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 883a39d..0000000
--- a/awt/java/awt/image/BufferedImageOp.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 27cee30..0000000
--- a/awt/java/awt/image/ByteLookupTable.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1a1700b..0000000
--- a/awt/java/awt/image/ColorConvertOp.java
+++ /dev/null
@@ -1,710 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1b084e1..0000000
--- a/awt/java/awt/image/ColorModel.java
+++ /dev/null
@@ -1,964 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 color space.
-     * @param hasAlpha
-     *            whether the color model has alpha.
-     * @param isAlphaPremultiplied
-     *            whether the alpha is pre-multiplied.
-     * @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 integer value 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 pre-multiplied 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 behavior.
-        // 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 normalized 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 integer value 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 integer value 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 normalized 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 unnormalized 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 integer, 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.
-     * @return the red component of the given pixel.
-     */
-    public abstract int getRed(int pixel);
-
-    /**
-     * Takes the pixel data and returns the integer value corresponding to the
-     * pixel's color in RGB format.
-     * 
-     * @param pixel
-     *            the pixel data.
-     * @return the corresponding RGB integer value.
-     */
-    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.
-     * @return the green component of the given 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 given 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 given 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 pre-multiplied.
-     * 
-     * @return true, if the alpha component is pre-multiplied.
-     */
-    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
deleted file mode 100644
index 4328fd3..0000000
--- a/awt/java/awt/image/ComponentColorModel.java
+++ /dev/null
@@ -1,1482 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 pre-multiplied.
-     * @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 pre-multiplied.
-     * @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
-     *            the integer representation of the pixel.
-     * @return the 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
-     *            the pixel.
-     * @param idx
-     *            the index of component.
-     * @return the 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
-     *            the pixel.
-     * @param idx
-     *            the index of component.
-     * @return the 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
deleted file mode 100644
index 7f81409..0000000
--- a/awt/java/awt/image/ComponentSampleModel.java
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 6eb8909..0000000
--- a/awt/java/awt/image/ConvolveOp.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2f4ca78..0000000
--- a/awt/java/awt/image/CropImageFilter.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 92f900f..0000000
--- a/awt/java/awt/image/DataBuffer.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 integer.
-     * 
-     * @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
deleted file mode 100644
index 3407de8..0000000
--- a/awt/java/awt/image/DataBufferByte.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 5d0a516..0000000
--- a/awt/java/awt/image/DataBufferDouble.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 9a4a6bf..0000000
--- a/awt/java/awt/image/DataBufferFloat.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 380a127..0000000
--- a/awt/java/awt/image/DataBufferInt.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 integer.
- * 
- * @since Android 1.0
- */
-public final class DataBufferInt extends DataBuffer {
-
-    /**
-     * The data.
-     */
-    int data[][];
-
-    /**
-     * Instantiates a new data buffer of type integer.
-     * 
-     * @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 integer.
-     * 
-     * @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 integer 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 integer 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 integer 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 integer 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
deleted file mode 100644
index 1b11b29..0000000
--- a/awt/java/awt/image/DataBufferShort.java
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 58d9d83..0000000
--- a/awt/java/awt/image/DataBufferUShort.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 700eb7a..0000000
--- a/awt/java/awt/image/DirectColorModel.java
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 pre-multiplied 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
-     *            the integer representation of the pixel.
-     * @param idx
-     *            the index of the pixel component.
-     * @return the value of the pixel component scaled from 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
-     *            the integer representation of the pixel.
-     * @param idx
-     *            the index of the pixel component.
-     * @return the value of the pixel component scaled from 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
-     *            the integer representation of the pixel.
-     * @param idx
-     *            the index of the pixel component.
-     * @return the value of the pixel component scaled from 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
deleted file mode 100644
index ed8558d..0000000
--- a/awt/java/awt/image/FilteredImageSource.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index caf87d1..0000000
--- a/awt/java/awt/image/ImageConsumer.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 occurred.
-     * </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
deleted file mode 100644
index d2c9f50..0000000
--- a/awt/java/awt/image/ImageFilter.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 21ec41b..0000000
--- a/awt/java/awt/image/ImageObserver.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 occurred.
-     */
-    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
deleted file mode 100644
index 9138be2..0000000
--- a/awt/java/awt/image/ImageProducer.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 adds 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
deleted file mode 100644
index e0c0127..0000000
--- a/awt/java/awt/image/ImagingOpException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 0b06acd..0000000
--- a/awt/java/awt/image/IndexColorModel.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *            the index into Color Map.
-     * @param pixel
-     *            the pixel
-     * @return the pixel representation array.
-     */
-    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 palette.
-     * 
-     * @return true, if is gray palette.
-     */
-    boolean isGrayPallete() {
-        return grayPalette;
-    }
-
-}
diff --git a/awt/java/awt/image/Kernel.java b/awt/java/awt/image/Kernel.java
deleted file mode 100644
index a59d27a..0000000
--- a/awt/java/awt/image/Kernel.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 3362c5c..0000000
--- a/awt/java/awt/image/LookupOp.java
+++ /dev/null
@@ -1,661 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 performs 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e465a54..0000000
--- a/awt/java/awt/image/LookupTable.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 an integer 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 integer 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
deleted file mode 100644
index 644fd40f..0000000
--- a/awt/java/awt/image/MemoryImageSource.java
+++ /dev/null
@@ -1,603 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 the {@code
-     * 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 the rectangular 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
deleted file mode 100644
index 3dc13d8..0000000
--- a/awt/java/awt/image/MultiPixelPackedSampleModel.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 behavior of this
-     * method depends on the method which has been invoke this one. The argument
-     * methodId is used to choose valid behavior 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
deleted file mode 100644
index 4d1c2e5..0000000
--- a/awt/java/awt/image/PackedColorModel.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 pre-multiplied 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 pre-multiplied 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
deleted file mode 100644
index cecd5c8..0000000
--- a/awt/java/awt/image/PixelGrabber.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 8e646f8..0000000
--- a/awt/java/awt/image/PixelInterleavedSampleModel.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index f5fe5d9..0000000
--- a/awt/java/awt/image/RGBImageFilter.java
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-public abstract class RGBImageFilter extends ImageFilter {
-
-    /**
-     * The original model is the ColorModel to be replaced by the new model when
-     * substituteColorModel is called.
-     */
-    protected ColorModel origmodel;
-
-    /**
-     * The new model is the ColorModel with which to replace the original model
-     * 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 of region.
-     * @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);
-    }
-
-    /**
-     * Converts 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
deleted file mode 100644
index 6749fde..0000000
--- a/awt/java/awt/image/Raster.java
+++ /dev/null
@@ -1,1515 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 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 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 raster. 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 indices.
-     * @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 integer 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 integer array where the result array will be stored.
-     * @return the integer 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 integer 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 integer 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
-     * integer.
-     * 
-     * @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
-     *         integer.
-     */
-    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 integer array of samples for the specified band of the specified
-     * rectangular area of pixels in this Raster as a integer 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 integer array.
-     * @return the integer 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
deleted file mode 100644
index c667141..0000000
--- a/awt/java/awt/image/RasterFormatException.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 19a84c9..0000000
--- a/awt/java/awt/image/RasterOp.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 5eafa64..0000000
--- a/awt/java/awt/image/RenderedImage.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 51c0f49..0000000
--- a/awt/java/awt/image/ReplicateScaleFilter.java
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 integer array of source rows.
-     */
-    protected int[] srcrows;
-
-    /**
-     * The integer 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
deleted file mode 100644
index d7e2bd7..0000000
--- a/awt/java/awt/image/RescaleOp.java
+++ /dev/null
@@ -1,659 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index c967fa6..0000000
--- a/awt/java/awt/image/SampleModel.java
+++ /dev/null
@@ -1,1166 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 an integer array.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param iArray
-     *            the integer array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the integer 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 integer array of samples.
-     * 
-     * @param x
-     *            the X coordinate of pixel.
-     * @param y
-     *            the Y coordinate of pixel.
-     * @param iArray
-     *            the integer 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
-     * integer.
-     * 
-     * @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 an
-     * integer 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 integer array where result will be stored.
-     * @param data
-     *            the image data.
-     * @return the integer 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 integer 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 integer 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 integer 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 integer 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 integer 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 integer 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 integer 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 integer 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 transferring via the
-     * getDataElements and setDataElements methods.
-     * 
-     * @return the number of data elements for pixel transferring 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
deleted file mode 100644
index 4319d58..0000000
--- a/awt/java/awt/image/ShortLookupTable.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 69f3353..0000000
--- a/awt/java/awt/image/SinglePixelPackedSampleModel.java
+++ /dev/null
@@ -1,519 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 7dd97e2..0000000
--- a/awt/java/awt/image/TileObserver.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index f24e866..0000000
--- a/awt/java/awt/image/VolatileImage.java
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
- * provides methods for checking if operation of this image are compatible for
- * the GraphicsConfiguration.
- * 
- * @since Android 1.0
- */
-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 specified GraphicsConfiguration object is applicable to this
-     * image.
-     * 
-     * @param gc
-     *            the 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
deleted file mode 100644
index 51366ee..0000000
--- a/awt/java/awt/image/WritableRaster.java
+++ /dev/null
@@ -1,592 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 indices.
-     * @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 an integer 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 integer 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 integer 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 integer 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 integer 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 integer 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
-     * integer 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 an
-     * integer 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
deleted file mode 100644
index 052353b..0000000
--- a/awt/java/awt/image/WritableRenderedImage.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
- * mechanism for obtaining tile's writing status.
- * 
- * @since Android 1.0
- */
-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 which 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/package.html b/awt/java/awt/image/package.html
deleted file mode 100644
index b4d6ef0..0000000
--- a/awt/java/awt/image/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces that allow to modify existing images or to create a new image rather than loading it from a file.
-    </p>
-   @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java b/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
deleted file mode 100644
index 1881a0c..0000000
--- a/awt/java/awt/image/renderable/ContextualRenderedImageFactory.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 7dde73a..0000000
--- a/awt/java/awt/image/renderable/ParameterBlock.java
+++ /dev/null
@@ -1,568 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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}.
- * 
- * @since Android 1.0
- */
-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;
-        }
-    }
-
-    /**
-     * Returns a copy of this ParameterBlock instance.
-     * 
-     * @return the identical copy of this instance.
-     */
-    @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 integer value in an Integer and places it in the parameter
-     * block at the specified index.
-     * 
-     * @param i
-     *            the integer 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 integer value in an Integer and adds it to the parameter block.
-     * 
-     * @param i
-     *            the integer 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 integer-valued parameter found at the desired index in the
-     * vector of parameter values.
-     * 
-     * @param index
-     *            the index.
-     * @return the integer 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
deleted file mode 100644
index 0db512f..0000000
--- a/awt/java/awt/image/renderable/RenderContext.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 21332f7..0000000
--- a/awt/java/awt/image/renderable/RenderableImage.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index dc45372..0000000
--- a/awt/java/awt/image/renderable/RenderableImageOp.java
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e83ebc7..0000000
--- a/awt/java/awt/image/renderable/RenderableImageProducer.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 881a40a..0000000
--- a/awt/java/awt/image/renderable/RenderedImageFactory.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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/image/renderable/package.html b/awt/java/awt/image/renderable/package.html
deleted file mode 100644
index 43aaabc..0000000
--- a/awt/java/awt/image/renderable/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes to create images which are rendering-independent.
-    </p>
-    @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/package.html b/awt/java/awt/package.html
deleted file mode 100644
index 5a6f9f0..0000000
--- a/awt/java/awt/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces for creating (graphical) user interfaces (GUI), painting 2D graphics and creating, manipulating and drawing images. 
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/java/awt/peer/ButtonPeer.java b/awt/java/awt/peer/ButtonPeer.java
deleted file mode 100644
index cc45b49..0000000
--- a/awt/java/awt/peer/ButtonPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index e276366..0000000
--- a/awt/java/awt/peer/CanvasPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 296f422..0000000
--- a/awt/java/awt/peer/CheckboxMenuItemPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index e9f8dd1..0000000
--- a/awt/java/awt/peer/CheckboxPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 57b7629..0000000
--- a/awt/java/awt/peer/ChoicePeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index bc26791..0000000
--- a/awt/java/awt/peer/ComponentPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 8ae3049..0000000
--- a/awt/java/awt/peer/DialogPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0d15e48..0000000
--- a/awt/java/awt/peer/FileDialogPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index fd9815f..0000000
--- a/awt/java/awt/peer/FontPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 9cfc40b..0000000
--- a/awt/java/awt/peer/FramePeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 052ca9d..0000000
--- a/awt/java/awt/peer/LabelPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1dee905..0000000
--- a/awt/java/awt/peer/LightweightPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0a27885..0000000
--- a/awt/java/awt/peer/ListPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 3ad2c16..0000000
--- a/awt/java/awt/peer/MenuBarPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 3ac3b34..0000000
--- a/awt/java/awt/peer/MenuComponentPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index b133897..0000000
--- a/awt/java/awt/peer/MenuItemPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index d643ce7..0000000
--- a/awt/java/awt/peer/MenuPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 9173a62..0000000
--- a/awt/java/awt/peer/MouseInfoPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1faa1fe..0000000
--- a/awt/java/awt/peer/PanelPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index cf1ef61..0000000
--- a/awt/java/awt/peer/PopupMenuPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index df3de83..0000000
--- a/awt/java/awt/peer/ScrollPanePeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index eec8961..0000000
--- a/awt/java/awt/peer/ScrollbarPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 636707f..0000000
--- a/awt/java/awt/peer/TextAreaPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 2b8232a..0000000
--- a/awt/java/awt/peer/TextFieldPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 384646f..0000000
--- a/awt/java/awt/peer/WindowPeer.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 2945c65..0000000
--- a/awt/java/beans/FeatureDescriptor.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- * http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * 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/IndexedPropertyDescriptor.java b/awt/java/beans/IndexedPropertyDescriptor.java
deleted file mode 100644
index 25667d9..0000000
--- a/awt/java/beans/IndexedPropertyDescriptor.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index c895afe..0000000
--- a/awt/java/beans/IntrospectionException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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/PropertyDescriptor.java b/awt/java/beans/PropertyDescriptor.java
deleted file mode 100644
index 9389152..0000000
--- a/awt/java/beans/PropertyDescriptor.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 65bedea..0000000
--- a/awt/java/beans/PropertyEditor.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index ed55829..0000000
--- a/awt/java/beans/PropertyEditorManager.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index c3929a1..0000000
--- a/awt/java/beans/PropertyEditorSupport.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index c7f092a..0000000
--- a/awt/java/beans/PropertyVetoException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index c77716c..0000000
--- a/awt/javax/imageio/IIOException.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e9e5130..0000000
--- a/awt/javax/imageio/IIOImage.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2ccc945..0000000
--- a/awt/javax/imageio/IIOParam.java
+++ /dev/null
@@ -1,342 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 338cb25..0000000
--- a/awt/javax/imageio/IIOParamController.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index e0d7ec9..0000000
--- a/awt/javax/imageio/ImageIO.java
+++ /dev/null
@@ -1,800 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 perform reading and writing
- * operations using registered ImageReader and ImageWriter objects.
- * 
- * @since Android 1.0
- */
-public final class ImageIO {
-
-    /**
-     * The constant registry.
-     */
-    private static final IIORegistry registry = IIORegistry.getDefaultInstance();
-
-    /**
-     * Instantiates a new ImageIO.
-     */
-    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
-     *             if 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
-     *             if 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
-     * input 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
deleted file mode 100644
index 9cc5c5f..0000000
--- a/awt/javax/imageio/ImageReadParam.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index cf282ed..0000000
--- a/awt/javax/imageio/ImageReader.java
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 instantiates 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
-     *             if 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 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 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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 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 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 width
-     *            the total width of the updated area.
-     * @param height
-     *            the total height of the 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 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
deleted file mode 100644
index 632d890..0000000
--- a/awt/javax/imageio/ImageTranscoder.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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 appropriate metadata object for
- * ImageWriter.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 505b1c4..0000000
--- a/awt/javax/imageio/ImageTypeSpecifier.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 pre-multiplied
-     *            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 pre-multiplied
-     *            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
-     *            pre-multiplied.
-     * @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 pre-multiplied 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 indices.
-     * @param greenLUT
-     *            the green values of indices.
-     * @param blueLUT
-     *            the blue values of indices.
-     * @param alphaLUT
-     *            the alpha values of indices.
-     * @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
deleted file mode 100644
index d661889..0000000
--- a/awt/javax/imageio/ImageWriteParam.java
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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, 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 describes 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
deleted file mode 100644
index 86879e0..0000000
--- a/awt/javax/imageio/ImageWriter.java
+++ /dev/null
@@ -1,1001 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 instantiates 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
-     *             if an I/O exception has occurred during writing.
-     */
-    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
-     *             if an I/O exception has occurred during writing.
-     */
-    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();
-    }
-
-    /**
-     * Returns 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    public void endInsertEmpty() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Ends the replace pixels operation.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void endReplacePixels() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Ends an empty write operation.
-     * 
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    public void endWriteEmpty() throws IOException {
-        unsupportedOperation();
-    }
-
-    /**
-     * Ends the sequence of write operations.
-     * 
-     * @throws IOException
-     *             if 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 supported 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if an I/O exception has occurred during writing.
-     */
-    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
deleted file mode 100644
index 2944896..0000000
--- a/awt/javax/imageio/event/IIOReadProgressListener.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 49bdbcb..0000000
--- a/awt/javax/imageio/event/IIOReadUpdateListener.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 integer 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 number 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 integer 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 number 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 integer 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 integer 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
deleted file mode 100644
index 318a5df..0000000
--- a/awt/javax/imageio/event/IIOReadWarningListener.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 4a2c595..0000000
--- a/awt/javax/imageio/event/IIOWriteProgressListener.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 8ee41cd..0000000
--- a/awt/javax/imageio/event/IIOWriteWarningListener.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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/event/package.html b/awt/javax/imageio/event/package.html
deleted file mode 100644
index c2fe39f..0000000
--- a/awt/javax/imageio/event/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package provides interfaces to handle events which can be fired during the reading or writing of images.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/metadata/IIOInvalidTreeException.java b/awt/javax/imageio/metadata/IIOInvalidTreeException.java
deleted file mode 100644
index ba90657..0000000
--- a/awt/javax/imageio/metadata/IIOInvalidTreeException.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 96cebf9..0000000
--- a/awt/javax/imageio/metadata/IIOMetadata.java
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1405948..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataController.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 0e7e697..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataFormat.java
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1a6e568..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataFormatImpl.java
+++ /dev/null
@@ -1,1056 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index efbaae8..0000000
--- a/awt/javax/imageio/metadata/IIOMetadataNode.java
+++ /dev/null
@@ -1,1080 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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;
-import org.w3c.dom.TypeInfo;
-import org.w3c.dom.UserDataHandler;
-
-//???AWT
-//import org.w3c.dom.TypeInfo;
-//import org.w3c.dom.UserDataHandler;
-
-/**
- * The Class IIOMetadataNode represents a node of the (DOM-style) metadata tree.
- * 
- * @since Android 1.0
- */
-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"); }
-     */
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Element (DOM Level
-     * 3)</i>
-     * <p>
-     * If the parameter isId is true, this method declares the specified
-     * attribute to be a user-determined ID attribute . This affects the value
-     * of Attr.isId and the behavior of Document.getElementById, but does not
-     * change any schema that may be in use, in particular this does not affect
-     * the Attr.schemaTypeInfo of the specified Attr node. Use the value false
-     * for the parameter isId to undeclare an attribute for being a
-     * user-determined ID attribute. To specify an attribute by local name and
-     * namespace URI, use the setIdAttributeNS method.
-     * </p>
-     * 
-     * @param name
-     *            the name of the attribute.
-     * @param isId
-     *            the flag which determines whether this attribute is of type
-     *            ID.
-     * @throws DOMException
-     *             if a DOM error occurred while setting the attribute type.
-     *             <p>
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *             <br>
-     *             NOT_FOUND_ERR: Raised if the specified node is not an
-     *             attribute of this element.
-     *             </p>
-     */
-    public void setIdAttribute(String name, boolean isId) throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Element (DOM Level
-     * 3)</i>
-     * <p>
-     * If the parameter isId is true, this method declares the specified
-     * attribute to be a user-determined ID attribute . This affects the value
-     * of Attr.isId and the behavior of Document.getElementById, but does not
-     * change any schema that may be in use, in particular this does not affect
-     * the Attr.schemaTypeInfo of the specified Attr node. Use the value false
-     * for the parameter isId to undeclare an attribute for being a
-     * user-determined ID attribute.
-     * </p>
-     * 
-     * @param namespaceURI
-     *            the namespace URI of the attribute.
-     * @param localName
-     *            the local name of the attribute.
-     * @param isId
-     *            the flag which determines whether this attribute is of type
-     *            ID.
-     * @throws DOMException
-     *             if a DOM error occurred while setting the attribute type.
-     *             <p>
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *             <br>
-     *             NOT_FOUND_ERR: Raised if the specified node is not an
-     *             attribute of this element.
-     *             </p>
-     */
-    public void setIdAttributeNS(String namespaceURI, String localName, boolean isId)
-            throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Element (DOM Level
-     * 3)</i>
-     * <p>
-     * If the parameter isId is true, this method declares the specified
-     * attribute to be a user-determined ID attribute . This affects the value
-     * of Attr.isId and the behavior of Document.getElementById, but does not
-     * change any schema that may be in use, in particular this does not affect
-     * the Attr.schemaTypeInfo of the specified Attr node. Use the value false
-     * for the parameter isId to undeclare an attribute for being a
-     * user-determined ID attribute.
-     * </p>
-     * 
-     * @param idAttr
-     *            the attribute node.
-     * @param isId
-     *            the flag which determines whether this attribute is of type
-     *            ID.
-     * @throws DOMException
-     *             if a DOM error occurred while setting the attribute type.
-     *             <p>
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly.
-     *             <br>
-     *             NOT_FOUND_ERR: Raised if the specified node is not an
-     *             attribute of this element.
-     *             </p>
-     */
-    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;
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * The absolute base URI of this node or null if the implementation wasn't
-     * able to obtain an absolute URI. This value is computed as described in.
-     * However, when the Document supports the feature "HTML" [DOM Level 2
-     * HTML], the base URI is computed using first the value of the href
-     * attribute of the HTML BASE element if any, and the value of the
-     * documentURI attribute from the Document interface otherwise.
-     * </p>
-     * 
-     * @return the string representation of the absolute base URI.
-     */
-    public String getBaseURI() {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Compares the reference node, i.e. the node on which this method is being
-     * called, with a node, i.e. the one passed as a parameter, with regard to
-     * their position in the document and according to the document order.
-     * </p>
-     * 
-     * @param other
-     *            the node to compare against the reference node.
-     * @return Returns how the node is positioned relatively to the reference
-     *         node.
-     * @throws DOMException
-     *             NOT_SUPPORTED_ERR: when the compared nodes are from different
-     *             DOM implementations that do not coordinate to return
-     *             consistent implementation-specific results.
-     */
-    public short compareDocumentPosition(Node other) throws DOMException {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This attribute returns the text content of this node and its descendants.
-     * When it is defined to be null, setting it has no effect. On setting, any
-     * possible children this node may have are removed and, if it the new
-     * string is not empty or null, replaced by a single Text node containing
-     * the string this attribute is set to. On getting, no serialization is
-     * performed, the returned string does not contain any markup. No whitespace
-     * normalization is performed and the returned string does not contain the
-     * white spaces in element content (see the attribute
-     * Text.isElementContentWhitespace). Similarly, on setting, no parsing is
-     * performed either, the input string is taken as pure textual content. The
-     * string returned is made of the text content of this node depending on its
-     * type, as defined below:
-     * <table>
-     * <tr>
-     * <td><strong>Node type</strong></td>
-     * <td><strong>Content</strong></td>
-     * </tr>
-     * <tr>
-     * <td>ELEMENT_NODE, ATTRIBUTE_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
-     * DOCUMENT_FRAGMENT_NODE</td>
-     * <td>concatenation of the textContent attribute value of every child node,
-     * excluding COMMENT_NODE and PROCESSING_INSTRUCTION_NODE nodes. This is the
-     * empty string if the node has no children.</td>
-     * </tr>
-     * <tr>
-     * <td>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
-     * PROCESSING_INSTRUCTION_NODE</td>
-     * <td>nodeValue</td>
-     * </tr>
-     * <tr>
-     * <td>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
-     * <td>null</td>
-     * </tr>
-     * </table>
-     * </p>
-     * 
-     * @return the text content depending on the type of this node.
-     * @throws DOMException
-     *             DOMSTRING_SIZE_ERR: Raised when it would return more
-     *             characters than fit in a DOMString variable on the
-     *             implementation platform.
-     */
-    public String getTextContent() throws DOMException {
-        return textContent;
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This attribute returns the text content of this node and its descendants.
-     * When it is defined to be null, setting it has no effect. On setting, any
-     * possible children this node may have are removed and, if it the new
-     * string is not empty or null, replaced by a single Text node containing
-     * the string this attribute is set to. On getting, no serialization is
-     * performed, the returned string does not contain any markup. No whitespace
-     * normalization is performed and the returned string does not contain the
-     * white spaces in element content (see the attribute
-     * Text.isElementContentWhitespace). Similarly, on setting, no parsing is
-     * performed either, the input string is taken as pure textual content. The
-     * string returned is made of the text content of this node depending on its
-     * type, as defined below:
-     * <table>
-     * <tr>
-     * <td><strong>Node type</strong></td>
-     * <td><strong>Content</strong></td>
-     * </tr>
-     * <tr>
-     * <td>ELEMENT_NODE, ATTRIBUTE_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE,
-     * DOCUMENT_FRAGMENT_NODE</td>
-     * <td>concatenation of the textContent attribute value of every child node,
-     * excluding COMMENT_NODE and PROCESSING_INSTRUCTION_NODE nodes. This is the
-     * empty string if the node has no children.</td>
-     * </tr>
-     * <tr>
-     * <td>TEXT_NODE, CDATA_SECTION_NODE, COMMENT_NODE,
-     * PROCESSING_INSTRUCTION_NODE</td>
-     * <td>nodeValue</td>
-     * </tr>
-     * <tr>
-     * <td>DOCUMENT_NODE, DOCUMENT_TYPE_NODE, NOTATION_NODE</td>
-     * <td>null</td>
-     * </tr>
-     * </table>
-     * </p>
-     * 
-     * @param textContent
-     *            the text content for this node.
-     * @throws DOMException
-     *             NO_MODIFICATION_ALLOWED_ERR: Raised when the node is
-     *             readonly.
-     */
-    public void setTextContent(String textContent) throws DOMException {
-        this.textContent = textContent;
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Returns whether this node is the same node as the given one. This method
-     * provides a way to determine whether two Node references returned by the
-     * implementation reference the same object. When two Node references are
-     * references to the same object, even if through a proxy, the references
-     * may be used completely interchangeably, such that all attributes have the
-     * same values and calling the same DOM method on either reference always
-     * has exactly the same effect.
-     * </p>
-     * 
-     * @param other
-     *            the node to test against.
-     * @return true, if the nodes are the same, false otherwise.
-     */
-    public boolean isSameNode(Node other) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Look up the prefix associated to the given namespace URI, starting from
-     * this node. The default namespace declarations are ignored by this method.
-     * See for details on the algorithm used by this method.
-     * </p>
-     * 
-     * @param namespaceURI
-     *            the namespace URI to look for.
-     * @return the associated namespace prefix if found or null if none is
-     *         found. If more than one prefix are associated to the namespace
-     *         prefix, the returned namespace prefix is implementation
-     *         dependent.
-     */
-    public String lookupPrefix(String namespaceURI) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This method checks if the specified namespaceURI is the default namespace
-     * or not.
-     * </p>
-     * 
-     * @param namespaceURI
-     *            the namespace URI to look for.
-     * @return true, if the specified namespaceURI is the default namespace,
-     *         false otherwise.
-     */
-    public boolean isDefaultNamespace(String namespaceURI) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Look up the namespace URI associated to the given prefix, starting from
-     * this node. See for details on the algorithm used by this method.
-     * </p>
-     * 
-     * @param prefix
-     *            the prefix to look for. If this parameter is null, the method
-     *            will return the default namespace URI if any.
-     * @return the associated namespace URI or null if none is found.
-     */
-    public String lookupNamespaceURI(String prefix) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Tests whether two nodes are equal. This method tests for equality of
-     * nodes, not sameness (i.e., whether the two nodes are references to the
-     * same object) which can be tested with Node.isSameNode(). All nodes that
-     * are the same will also be equal, though the reverse may not be true. Two
-     * nodes are equal if and only if the following conditions are satisfied:
-     * <p>
-     * <li>The two nodes are of the same type.</li>
-     * <li>The following string attributes are equal: nodeName, localName,
-     * namespaceURI, prefix, nodeValue . This is: they are both null, or they
-     * have the same length and are character for character identical.</li>
-     * <li>The attributes NamedNodeMaps are equal. This is: they are both null,
-     * or they have the same length and for each node that exists in one map
-     * there is a node that exists in the other map and is equal, although not
-     * necessarily at the same index.</li>
-     * <li>The childNodes NodeLists are equal. This is: they are both null, or
-     * they have the same length and contain equal nodes at the same index. Note
-     * that normalization can affect equality; to avoid this, nodes should be
-     * normalized before being compared.</li>
-     * </p>
-     * For two DocumentType nodes to be equal, the following conditions must
-     * also be satisfied:
-     * <p>
-     * <li>The following string attributes are equal: publicId, systemId,
-     * internalSubset.</li>
-     * <li>The entities NamedNodeMaps are equal.</li>
-     * <li>The notations NamedNodeMaps are equal.</li>
-     * </p>
-     * On the other hand, the following do not affect equality: the
-     * ownerDocument, baseURI, and parentNode attributes, the specified
-     * attribute for Attr nodes, the schemaTypeInfo attribute for Attr and
-     * Element nodes, the Text.isElementContentWhitespace attribute for Text
-     * nodes, as well as any user data or event listeners registered on the
-     * nodes. </p>
-     * <p>
-     * Note: As a general rule, anything not mentioned in the description above
-     * is not significant in consideration of equality checking. Note that
-     * future versions of this specification may take into account more
-     * attributes and implementations conform to this specification are expected
-     * to be updated accordingly.
-     * </p>
-     * 
-     * @param arg
-     *            the node to compare equality with.
-     * @return true, if the nodes are equal, false otherwise.
-     */
-    public boolean isEqualNode(Node arg) {
-        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Method not supported");
-    }
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * This method returns a specialized object which implements the specialized
-     * APIs of the specified feature and version, as specified in. The
-     * specialized object may also be obtained by using binding-specific casting
-     * methods but is not necessarily expected to, as discussed in. This method
-     * also allow the implementation to provide specialized objects which do not
-     * support the Node interface.
-     * </p>
-     * 
-     * @param feature
-     *            the name of the feature requested. Note that any plus sign "+"
-     *            prepended to the name of the feature will be ignored since it
-     *            is not significant in the context of this method.
-     * @param version
-     *            this is the version number of the feature to test.
-     * @return the object which implements the specialized APIs of the specified
-     *         feature and version, if any, or null if there is no object which
-     *         implements interfaces associated with that feature. If the
-     *         DOMObject returned by this method implements the Node interface,
-     *         it must delegate to the primary core Node and not return results
-     *         inconsistent with the primary core Node such as attributes,
-     *         childNodes, etc.
-     */
-    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"); }
-     */
-
-    /**
-     * <i>Description copied from interface: org.w3c.dom.Node (DOM Level 3)</i>
-     * <p>
-     * Retrieves the object associated to a key on a this node. The object must
-     * first have been set to this node by calling setUserData with the same
-     * key.
-     * </p>
-     * 
-     * @param key
-     *            the key the object is associated to.
-     * @return the DOMUserData associated to the given key on this node, or null
-     *         if there was none.
-     */
-    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;
-    }
-
-    public TypeInfo getSchemaTypeInfo() {
-        throw new UnsupportedOperationException();
-    }
-
-    public Object setUserData(String key, Object data, UserDataHandler handler) {
-        throw new UnsupportedOperationException();
-    }
-
-    /**
-     * 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;
-        }
-
-        /**
-         * @return
-         */
-        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
deleted file mode 100644
index 706cb2f..0000000
--- a/awt/javax/imageio/metadata/IIOStandardMetadataFormat.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index d185808..0000000
--- a/awt/javax/imageio/metadata/IIOStandardMetadataFormatResources.properties
+++ /dev/null
@@ -1,133 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT 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/metadata/package.html b/awt/javax/imageio/metadata/package.html
deleted file mode 100644
index 29bd51b..0000000
--- a/awt/javax/imageio/metadata/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes which allows to read and write describing metadata of image files.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/package.html b/awt/javax/imageio/package.html
deleted file mode 100644
index 2fd6148..0000000
--- a/awt/javax/imageio/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces which provides an Image I/O API. The contained classes and interfaces allow reading and writing image files of different formats.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java b/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
deleted file mode 100644
index ecfb20a..0000000
--- a/awt/javax/imageio/plugins/bmp/BMPImageWriteParam.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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/bmp/package.html b/awt/javax/imageio/plugins/bmp/package.html
deleted file mode 100644
index 9494a10..0000000
--- a/awt/javax/imageio/plugins/bmp/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains auxiliary classes for the built-in BMP image plug-in.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java b/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
deleted file mode 100644
index 67b504b..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGHuffmanTable.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 2f3a9a8..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGImageReadParam.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index b979911..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGImageWriteParam.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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 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
deleted file mode 100644
index 3461d46..0000000
--- a/awt/javax/imageio/plugins/jpeg/JPEGQTable.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 standard 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 integer values.
-     * 
-     * @return the current quantization table as an array of integer 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/plugins/jpeg/package.html b/awt/javax/imageio/plugins/jpeg/package.html
deleted file mode 100644
index 14575c4..0000000
--- a/awt/javax/imageio/plugins/jpeg/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains auxiliary classes for the built-in JPEG image plug-in.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/spi/IIORegistry.java b/awt/javax/imageio/spi/IIORegistry.java
deleted file mode 100644
index 01ddeaa..0000000
--- a/awt/javax/imageio/spi/IIORegistry.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 built-in 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
deleted file mode 100644
index e947677..0000000
--- a/awt/javax/imageio/spi/IIOServiceProvider.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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).
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index fc859a8..0000000
--- a/awt/javax/imageio/spi/ImageInputStreamSpi.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 the
-     * 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
-     *             if 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
-     *             if 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
deleted file mode 100644
index b7a9a5c..0000000
--- a/awt/javax/imageio/spi/ImageOutputStreamSpi.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *             if 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
-     *             if 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
deleted file mode 100644
index 0528d25..0000000
--- a/awt/javax/imageio/spi/ImageReaderSpi.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 plug-in 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
-     *            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 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
-     *             if 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
-     *             if 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 plug-in specific extension object, or null.
-     * @return the ImageReader.
-     * @throws IOException
-     *             if 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 the 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
deleted file mode 100644
index 9ca08b5..0000000
--- a/awt/javax/imageio/spi/ImageReaderWriterSpi.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 plug-in 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 plug-in class name.
-     * @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 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 the 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 the 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
deleted file mode 100644
index 742af19..0000000
--- a/awt/javax/imageio/spi/ImageTranscoderSpi.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index bf25455..0000000
--- a/awt/javax/imageio/spi/ImageWriterSpi.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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 plug-in 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
-     *             if 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 plug-in specific extension object, or null.
-     * @return the ImageWriter.
-     * @throws IOException
-     *             if 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 the 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
deleted file mode 100644
index ae2f4d3..0000000
--- a/awt/javax/imageio/spi/RegisterableService.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 79b02a3..0000000
--- a/awt/javax/imageio/spi/ServiceRegistry.java
+++ /dev/null
@@ -1,552 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *             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.
-     * 
-     * @since Android 1.0
-     */
-    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 true, 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/spi/package.html b/awt/javax/imageio/spi/package.html
deleted file mode 100644
index 18ceff4..0000000
--- a/awt/javax/imageio/spi/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-    This package provides several Service Provider Interface (SPI) classes for readers, writers, transcoders and streams to handle images.
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/javax/imageio/stream/FileCacheImageInputStream.java b/awt/javax/imageio/stream/FileCacheImageInputStream.java
deleted file mode 100644
index 710ac66..0000000
--- a/awt/javax/imageio/stream/FileCacheImageInputStream.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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 cache file will be created.
-     * @throws IOException
-     *             if 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
deleted file mode 100644
index 135afab..0000000
--- a/awt/javax/imageio/stream/FileCacheImageOutputStream.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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 cache file will be created.
-     * @throws IOException
-     *             if 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
deleted file mode 100644
index b9b6002..0000000
--- a/awt/javax/imageio/stream/FileImageInputStream.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
-     *             if 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
deleted file mode 100644
index 2730ba6..0000000
--- a/awt/javax/imageio/stream/FileImageOutputStream.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *             if 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
deleted file mode 100644
index 867d808..0000000
--- a/awt/javax/imageio/stream/IIOByteBuffer.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 3dec5d2..0000000
--- a/awt/javax/imageio/stream/ImageInputStream.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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 the boolean value for read byte.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    boolean readBoolean() throws IOException;
-
-    /**
-     * Reads a byte from the stream and returns its value as signed byte.
-     * 
-     * @return the signed byte value for read byte.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    byte readByte() throws IOException;
-
-    /**
-     * Reads a byte from the stream and returns its value as an integer.
-     * 
-     * @return the unsigned byte value for read byte as an integer.
-     * @throws IOException
-     *             if 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
-     *             if 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 integer.
-     * @throws IOException
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    char readChar() throws IOException;
-
-    /**
-     * Reads 4 bytes from the stream, and returns the result as an integer.
-     * 
-     * @return the signed integer value from the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int readInt() throws IOException;
-
-    /**
-     * Reads 4 bytes from the stream and returns its value as long.
-     * 
-     * @return the unsigned integer value as long.
-     * @throws IOException
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    void readFully(char[] c, int off, int len) throws IOException;
-
-    /**
-     * Reads the specified number of integer from the stream, and stores the
-     * result into the specified array starting at the specified index offset.
-     * 
-     * @param i
-     *            the integer array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of integer to be read.
-     * @throws IOException
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    long getStreamPosition() throws IOException;
-
-    /**
-     * Gets the bit offset.
-     * 
-     * @return the bit offset.
-     * @throws IOException
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    long length() throws IOException;
-
-    /**
-     * Skips the specified number of bytes by moving stream position.
-     * 
-     * @param n
-     *            the number of bytes.
-     * @return the actual skipped number of bytes.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    int skipBytes(int n) throws IOException;
-
-    /**
-     * Skips the specified number of bytes by moving stream position.
-     * 
-     * @param n
-     *            the number of bytes.
-     * @return the actual skipped number of bytes.
-     * @throws IOException
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
deleted file mode 100644
index d79da41..0000000
--- a/awt/javax/imageio/stream/ImageInputStreamImpl.java
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *             if 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
deleted file mode 100644
index 28ec932..0000000
--- a/awt/javax/imageio/stream/ImageOutputStream.java
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-public interface ImageOutputStream extends DataOutput, ImageInputStream {
-
-    /**
-     * Writes a single byte to the stream at the current position.
-     * 
-     * @param b
-     *            the integer value, of which the 8 lowest bits will be written.
-     * @throws IOException
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    void write(byte[] b) throws IOException;
-
-    /**
-     * Writes a number of bytes from the specified byte array beginning from the
-     * specified offset.
-     * 
-     * @param b
-     *            the byte array.
-     * @param off
-     *            the offset.
-     * @param len
-     *            the number of bytes to be written.
-     * @throws IOException
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    void writeBoolean(boolean b) throws IOException;
-
-    /**
-     * Writes the 8 lowest bits of the specified integer value to the stream.
-     * 
-     * @param b
-     *            the specified integer value.
-     * @throws IOException
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    void writeShort(int v) throws IOException;
-
-    /**
-     * Writes the 16 lowest bits of the specified integer value to the stream.
-     * 
-     * @param v
-     *            the specified integer value.
-     * @throws IOException
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    void writeInt(int v) throws IOException;
-
-    /**
-     * Write long.
-     * 
-     * @param v
-     *            the long value.
-     * @throws IOException
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if an I/O exception has occurred.
-     */
-    void writeChars(char[] c, int off, int len) throws IOException;
-
-    /**
-     * Writes a len number of integer values from the specified array to the
-     * stream.
-     * 
-     * @param i
-     *            the integer array to be written.
-     * @param off
-     *            the offset in the char array.
-     * @param len
-     *            the length of chars to be written.
-     * @throws IOException
-     *             if 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
-     *             if 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
-     *             if 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
-     *             if 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 integer whose least significant bit is to be written to
-     *            the stream.
-     * @throws IOException
-     *             if an I/O exception has occurred.
-     */
-    void writeBit(int bit) throws IOException;
-
-    /**
-     * Writes a sequence of bits beginning from the current position.
-     * 
-     * @param bits
-     *            the 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
-     *             if 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
deleted file mode 100644
index 0fef78f..0000000
--- a/awt/javax/imageio/stream/ImageOutputStreamImpl.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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.
- * 
- * @since Android 1.0
- */
-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
-     *             if 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
deleted file mode 100644
index d7fc791..0000000
--- a/awt/javax/imageio/stream/MemoryCacheImageInputStream.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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
deleted file mode 100644
index 1df40a3..0000000
--- a/awt/javax/imageio/stream/MemoryCacheImageOutputStream.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.
- * 
- * @since Android 1.0
- */
-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/javax/imageio/stream/package.html b/awt/javax/imageio/stream/package.html
deleted file mode 100644
index 6cf53c3..0000000
--- a/awt/javax/imageio/stream/package.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<html>
-  <body>
-    <p>
-      This package contains classes and interfaces for handling images with low-level I/O operations. 
-    </p>
-  @since Android 1.0
-  </body>
-</html>
diff --git a/awt/org/apache/harmony/awt/ChoiceStyle.java b/awt/org/apache/harmony/awt/ChoiceStyle.java
deleted file mode 100644
index 93b7aad..0000000
--- a/awt/org/apache/harmony/awt/ChoiceStyle.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c89a81d..0000000
--- a/awt/org/apache/harmony/awt/ClipRegion.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c359784..0000000
--- a/awt/org/apache/harmony/awt/ComponentInternals.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index d44648a..0000000
--- a/awt/org/apache/harmony/awt/ContextStorage.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 4f0af52..0000000
--- a/awt/org/apache/harmony/awt/ContextThreadGroup.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index f5c55f1..0000000
--- a/awt/org/apache/harmony/awt/ListenerList.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 671653f..0000000
--- a/awt/org/apache/harmony/awt/ReadOnlyIterator.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index bd5f6c6..0000000
--- a/awt/org/apache/harmony/awt/gl/AwtImageBackdoorAccessor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index a33c38b..0000000
--- a/awt/org/apache/harmony/awt/gl/CommonGraphics2D.java
+++ /dev/null
@@ -1,1132 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 27e3ef0..0000000
--- a/awt/org/apache/harmony/awt/gl/CommonGraphics2DFactory.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 5c78e50..0000000
--- a/awt/org/apache/harmony/awt/gl/CommonGraphicsEnvironment.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index ae7fb0e..0000000
--- a/awt/org/apache/harmony/awt/gl/Crossing.java
+++ /dev/null
@@ -1,889 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 177be23..0000000
--- a/awt/org/apache/harmony/awt/gl/GLVolatileImage.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index fc5631f..0000000
--- a/awt/org/apache/harmony/awt/gl/ICompositeContext.java
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 6368dd8..0000000
--- a/awt/org/apache/harmony/awt/gl/ImageSurface.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c4267f3..0000000
--- a/awt/org/apache/harmony/awt/gl/MultiRectArea.java
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c75e203..0000000
--- a/awt/org/apache/harmony/awt/gl/MultiRectAreaOp.java
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 8b0ae38..0000000
--- a/awt/org/apache/harmony/awt/gl/Surface.java
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index f57952d..0000000
--- a/awt/org/apache/harmony/awt/gl/TextRenderer.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index e27e1d3..0000000
--- a/awt/org/apache/harmony/awt/gl/XORComposite.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c98e114..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ColorConverter.java
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index a1cc169..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ColorScaler.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 2f7e519..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ICC_ProfileHelper.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 27646c4..0000000
--- a/awt/org/apache/harmony/awt/gl/color/ICC_Transform.java
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 5ea6d25..0000000
--- a/awt/org/apache/harmony/awt/gl/color/LUTColorConverter.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 7f8c7e6..0000000
--- a/awt/org/apache/harmony/awt/gl/color/NativeCMM.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 9594047..0000000
--- a/awt/org/apache/harmony/awt/gl/color/NativeImageFormat.java
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index e8ad1bb..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidFont.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 063a256..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidFontManager.java
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0cfdc43..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidFontProperty.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index f3b2e28..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidGlyphVector.java
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (C) 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 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
deleted file mode 100644
index f37be6d..0000000
--- a/awt/org/apache/harmony/awt/gl/font/AndroidLineMetrics.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c0fb390..0000000
--- a/awt/org/apache/harmony/awt/gl/font/BasicMetrics.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index b18bdd5..0000000
--- a/awt/org/apache/harmony/awt/gl/font/CaretManager.java
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 4040a60..0000000
--- a/awt/org/apache/harmony/awt/gl/font/CommonGlyphVector.java
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 70cb334..0000000
--- a/awt/org/apache/harmony/awt/gl/font/CompositeFont.java
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 047ba6d..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontExtraMetrics.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 09bcf5c..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontFinder.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 8354e25..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontManager.java
+++ /dev/null
@@ -1,819 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 7783317..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontMetricsImpl.java
+++ /dev/null
@@ -1,282 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 14ff997..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontPeerImpl.java
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 4eb7cbb..0000000
--- a/awt/org/apache/harmony/awt/gl/font/FontProperty.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 44b8809..0000000
--- a/awt/org/apache/harmony/awt/gl/font/Glyph.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 370146d..0000000
--- a/awt/org/apache/harmony/awt/gl/font/LineMetricsImpl.java
+++ /dev/null
@@ -1,412 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 81905fd..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextDecorator.java
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index be5762a..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextMetricsCalculator.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index be606f7..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextRunBreaker.java
+++ /dev/null
@@ -1,861 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1cd2c05..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextRunSegment.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0ec2d05..0000000
--- a/awt/org/apache/harmony/awt/gl/font/TextRunSegmentImpl.java
+++ /dev/null
@@ -1,979 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index f1d64fb..0000000
--- a/awt/org/apache/harmony/awt/gl/image/BufferedImageGraphics2D.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0fe25a2..0000000
--- a/awt/org/apache/harmony/awt/gl/image/BufferedImageSource.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index cc6d7cf..0000000
--- a/awt/org/apache/harmony/awt/gl/image/ByteArrayDecodingImageSource.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 8793050..0000000
--- a/awt/org/apache/harmony/awt/gl/image/DataBufferListener.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 958d691..0000000
--- a/awt/org/apache/harmony/awt/gl/image/DecodingImageSource.java
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 54d4664..0000000
--- a/awt/org/apache/harmony/awt/gl/image/FileDecodingImageSource.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 7ecb15b..0000000
--- a/awt/org/apache/harmony/awt/gl/image/GifDecoder.java
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index d16128e..0000000
--- a/awt/org/apache/harmony/awt/gl/image/ImageDecoder.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 5c7d180..0000000
--- a/awt/org/apache/harmony/awt/gl/image/ImageLoader.java
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 2e64427..0000000
--- a/awt/org/apache/harmony/awt/gl/image/JpegDecoder.java
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
-*  Licensed to the Apache Software Foundation (ASF) under one or more
-*  contributor license agreements.  See the NOTICE file distributed with
-*  this work for additional information regarding copyright ownership.
-*  The ASF licenses this file to You under the Apache License, Version 2.0
-*  (the "License"); you may not use this file except in compliance with
-*  the License.  You may obtain a copy of the License at
-*
-*     http://www.apache.org/licenses/LICENSE-2.0
-*
-*  Unless required by applicable law or agreed to in writing, software
-*  distributed under the License is distributed on an "AS IS" BASIS,
-*  WITHOUT WARRANTIES 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
deleted file mode 100644
index 3445f8e..0000000
--- a/awt/org/apache/harmony/awt/gl/image/OffscreenImage.java
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1748e1b..0000000
--- a/awt/org/apache/harmony/awt/gl/image/OrdinaryWritableRaster.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 7e85600..0000000
--- a/awt/org/apache/harmony/awt/gl/image/PngDecoder.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index bfb2b51..0000000
--- a/awt/org/apache/harmony/awt/gl/image/PngDecoderJava.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 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 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);
-  }
-}
diff --git a/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java b/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
deleted file mode 100644
index a1899d6..0000000
--- a/awt/org/apache/harmony/awt/gl/image/URLDecodingImageSource.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 3b8012e..0000000
--- a/awt/org/apache/harmony/awt/gl/render/Blitter.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index b643b41..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaArcRasterizer.java
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 67e0a59..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaBlitter.java
+++ /dev/null
@@ -1,611 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index eb6f7b5..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaLineRasterizer.java
+++ /dev/null
@@ -1,760 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index dbaaf53..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaShapeRasterizer.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 322ba57..0000000
--- a/awt/org/apache/harmony/awt/gl/render/JavaTextRenderer.java
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index b0ebc97..0000000
--- a/awt/org/apache/harmony/awt/gl/render/NativeImageBlitter.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 9032e4e..0000000
--- a/awt/org/apache/harmony/awt/gl/render/NullBlitter.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 45ed11f..0000000
--- a/awt/org/apache/harmony/awt/im/InputMethodContext.java
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c340358..0000000
--- a/awt/org/apache/harmony/awt/internal/nls/Messages.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg);
-        // END android-changed
-    }
-
-    /**
-     * 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) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java b/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
deleted file mode 100644
index b57fe11..0000000
--- a/awt/org/apache/harmony/awt/internal/nls/MsgHelp.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index b13e50b..0000000
--- a/awt/org/apache/harmony/awt/state/MenuItemState.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 564a49a..0000000
--- a/awt/org/apache/harmony/awt/state/MenuState.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 4b8706d..0000000
--- a/awt/org/apache/harmony/awt/state/State.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 63c581d..0000000
--- a/awt/org/apache/harmony/awt/wtk/CreationParams.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 35e7d33..0000000
--- a/awt/org/apache/harmony/awt/wtk/CursorFactory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0d7c84f..0000000
--- a/awt/org/apache/harmony/awt/wtk/GraphicsFactory.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1f8a29a..0000000
--- a/awt/org/apache/harmony/awt/wtk/KeyInfo.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 2c6eb1e..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeCursor.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1471c1a..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeEvent.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0738cd1..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeEventQueue.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index d50add4..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeEventThread.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 1626f4a..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeIM.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0696975..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeMouseInfo.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 0b354d0..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeRobot.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 73fd6c0..0000000
--- a/awt/org/apache/harmony/awt/wtk/NativeWindow.java
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 701eb46..0000000
--- a/awt/org/apache/harmony/awt/wtk/ShutdownThread.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 6efa519..0000000
--- a/awt/org/apache/harmony/awt/wtk/ShutdownWatchdog.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 3eeaa0b..0000000
--- a/awt/org/apache/harmony/awt/wtk/Synchronizer.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 6b59f0e..0000000
--- a/awt/org/apache/harmony/awt/wtk/SystemProperties.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 4162fbd..0000000
--- a/awt/org/apache/harmony/awt/wtk/WTK.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 23604da..0000000
--- a/awt/org/apache/harmony/awt/wtk/WindowFactory.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 51e8168..0000000
--- a/awt/org/apache/harmony/beans/internal/nls/Messages.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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;
-
-// 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.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 {
-
-    // BEGIN android-deleted
-    // private static final String sResource =
-    //     "org.apache.harmony.beans.internal.nls.messages"; //$NON-NLS-1$
-    // 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) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg);
-        // END android-changed
-    }
-
-    /**
-     * 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) {
-        // BEGIN android-changed
-        return MsgHelp.getString(msg, args);
-        // END android-changed
-    }
-
-    // BEGIN android-note
-    // Duplicate code was dropped in favor of using MsgHelp.
-    // END android-note
-}
diff --git a/awt/org/apache/harmony/beans/internal/nls/MsgHelp.java b/awt/org/apache/harmony/beans/internal/nls/MsgHelp.java
deleted file mode 100644
index 68faabf..0000000
--- a/awt/org/apache/harmony/beans/internal/nls/MsgHelp.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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.beans.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/beans/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/x/imageio/internal/nls/Messages.java b/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
deleted file mode 100644
index 498e1bb..0000000
--- a/awt/org/apache/harmony/x/imageio/internal/nls/Messages.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *     http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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
deleted file mode 100644
index 8a49dd8..0000000
--- a/awt/org/apache/harmony/x/imageio/internal/nls/messages.properties
+++ /dev/null
@@ -1,18 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT 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
deleted file mode 100644
index caeefdd..0000000
--- a/awt/org/apache/harmony/x/imageio/metadata/IIOMetadataUtils.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 051f906..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/IISDecodingImageSource.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 067a825..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGConsts.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 110ed23..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReader.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c719ce7..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageReaderSpi.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index ae3e876..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriter.java
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index b7990e0..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGImageWriterSpi.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index c3b4a50..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/jpeg/JPEGSpiConsts.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 480041c..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReader.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 50f8b10..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageReaderSpi.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index e2a8d7d..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriter.java
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index bf3a000..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterParam.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 6eed14d..0000000
--- a/awt/org/apache/harmony/x/imageio/plugins/png/PNGImageWriterSpi.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index d4fdd76..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/FileIISSpi.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index acda6a1..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/FileIOSSpi.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index ed2fef0..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/InputStreamIISSpi.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index dd1e88d..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/OutputStreamIOSSpi.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index f97eb87..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/RAFIISSpi.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index a9d3649..0000000
--- a/awt/org/apache/harmony/x/imageio/spi/RAFIOSSpi.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES 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
deleted file mode 100644
index 64f7b2a..0000000
--- a/awt/org/apache/harmony/x/imageio/stream/RandomAccessMemoryCache.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT 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
deleted file mode 100644
index 9f647e9..0000000
--- a/awt/resources/org/apache/harmony/awt/internal/nls/messages.properties
+++ /dev/null
@@ -1,495 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT 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}
diff --git a/awt/resources/org/apache/harmony/beans/internals/nls/messages.properties b/awt/resources/org/apache/harmony/beans/internals/nls/messages.properties
deleted file mode 100644
index 72b1c8c..0000000
--- a/awt/resources/org/apache/harmony/beans/internals/nls/messages.properties
+++ /dev/null
@@ -1,103 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#  
-#      http://www.apache.org/licenses/LICENSE-2.0
-#  
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT 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/cmds/surfaceflinger/main_surfaceflinger.cpp b/cmds/surfaceflinger/main_surfaceflinger.cpp
index d650721..78b1007 100644
--- a/cmds/surfaceflinger/main_surfaceflinger.cpp
+++ b/cmds/surfaceflinger/main_surfaceflinger.cpp
@@ -1,18 +1,25 @@
-#include <binder/IPCThreadState.h>
-#include <binder/ProcessState.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
+/*
+ * Copyright (C) 2010 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.
+ */
 
+#include <binder/BinderService.h>
 #include <SurfaceFlinger.h>
 
 using namespace android;
 
-int main(int argc, char** argv)
-{
-    sp<ProcessState> proc(ProcessState::self());
-    sp<IServiceManager> sm = defaultServiceManager();
-    LOGI("ServiceManager: %p", sm.get());
-    SurfaceFlinger::instantiate();
-    ProcessState::self()->startThreadPool();
-    IPCThreadState::self()->joinThreadPool();
+int main(int argc, char** argv) {
+    SurfaceFlinger::publishAndJoinThreadPool();
+    return 0;
 }
diff --git a/include/binder/BinderService.h b/include/binder/BinderService.h
new file mode 100644
index 0000000..2316fef
--- /dev/null
+++ b/include/binder/BinderService.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_BINDER_SERVICE_H
+#define ANDROID_BINDER_SERVICE_H
+
+#include <stdint.h>
+
+#include <utils/Errors.h>
+#include <utils/String16.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+template<typename SERVICE>
+class BinderService
+{
+public:
+    static status_t publish() {
+        sp<IServiceManager> sm(defaultServiceManager());
+        return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
+    }
+
+    static void publishAndJoinThreadPool() {
+        sp<ProcessState> proc(ProcessState::self());
+        sp<IServiceManager> sm(defaultServiceManager());
+        sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
+        ProcessState::self()->startThreadPool();
+        IPCThreadState::self()->joinThreadPool();
+    }
+
+    static void instantiate() { publish(); }
+
+    static status_t shutdown() {
+        return NO_ERROR;
+    }
+};
+
+
+}; // namespace android
+// ---------------------------------------------------------------------------
+#endif // ANDROID_BINDER_SERVICE_H
diff --git a/include/binder/IPCThreadState.h b/include/binder/IPCThreadState.h
index 3ab985d..b54718f 100644
--- a/include/binder/IPCThreadState.h
+++ b/include/binder/IPCThreadState.h
@@ -40,7 +40,13 @@
 
             int                 getCallingPid();
             int                 getCallingUid();
-            
+
+            void                setStrictModePolicy(int32_t policy);
+            int32_t             getStrictModePolicy() const;
+
+            void                setLastTransactionBinderFlags(int32_t flags);
+            int32_t             getLastTransactionBinderFlags() const;
+
             int64_t             clearCallingIdentity();
             void                restoreCallingIdentity(int64_t token);
             
@@ -109,8 +115,10 @@
             status_t            mLastError;
             pid_t               mCallingPid;
             uid_t               mCallingUid;
+            int32_t             mStrictModePolicy;
+            int32_t             mLastTransactionBinderFlags;
 };
-    
+
 }; // namespace android
 
 // ---------------------------------------------------------------------------
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 66c34b2..32c9a1d 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -26,11 +26,12 @@
 // ---------------------------------------------------------------------------
 namespace android {
 
+class Flattenable;
 class IBinder;
+class IPCThreadState;
 class ProcessState;
 class String8;
 class TextOutput;
-class Flattenable;
 
 struct flat_binder_object;  // defined in support_p/binder_module.h
 
@@ -56,9 +57,19 @@
 
     bool                hasFileDescriptors() const;
 
+    // Writes the RPC header.
     status_t            writeInterfaceToken(const String16& interface);
-    bool                enforceInterface(const String16& interface) const;
-    bool                checkInterface(IBinder*) const;    
+
+    // Parses the RPC header, returning true if the interface name
+    // in the header matches the expected interface from the caller.
+    //
+    // Additionally, enforceInterface does part of the work of
+    // propagating the StrictMode policy mask, populating the current
+    // IPCThreadState, which as an optimization may optionally be
+    // passed in.
+    bool                enforceInterface(const String16& interface,
+                                         IPCThreadState* threadState = NULL) const;
+    bool                checkInterface(IBinder*) const;
 
     void                freeData();
 
@@ -100,6 +111,11 @@
     
     status_t            writeObject(const flat_binder_object& val, bool nullMetaData);
 
+    // Like Parcel.java's writeNoException().  Just writes a zero int32.
+    // Currently the native implementation doesn't do any of the StrictMode
+    // stack gathering and serialization that the Java implementation does.
+    status_t            writeNoException();
+
     void                remove(size_t start, size_t amt);
     
     status_t            read(void* outData, size_t len) const;
@@ -122,7 +138,14 @@
     sp<IBinder>         readStrongBinder() const;
     wp<IBinder>         readWeakBinder() const;
     status_t            read(Flattenable& val) const;
-    
+
+    // Like Parcel.java's readExceptionCode().  Reads the first int32
+    // off of a Parcel's header, returning 0 or the negative error
+    // code on exceptions, but also deals with skipping over rich
+    // response headers.  Callers should use this to read & parse the
+    // response headers rather than doing it by hand.
+    int32_t             readExceptionCode() const;
+
     // Retrieve native_handle from the parcel. This returns a copy of the
     // parcel's native_handle (the caller takes ownership). The caller
     // must free the native_handle with native_handle_close() and 
diff --git a/include/gui/ISensorEventConnection.h b/include/gui/ISensorEventConnection.h
new file mode 100644
index 0000000..ed4e4cc
--- /dev/null
+++ b/include/gui/ISensorEventConnection.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
+#define ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class SensorChannel;
+
+class ISensorEventConnection : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SensorEventConnection);
+
+    virtual sp<SensorChannel> getSensorChannel() const = 0;
+    virtual status_t enableDisable(int handle, bool enabled) = 0;
+    virtual status_t setEventRate(int handle, nsecs_t ns) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSensorEventConnection : public BnInterface<ISensorEventConnection>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_ISENSOR_EVENT_CONNECTION_H
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
new file mode 100644
index 0000000..9c8afc5
--- /dev/null
+++ b/include/gui/ISensorServer.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_GUI_ISENSORSERVER_H
+#define ANDROID_GUI_ISENSORSERVER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+class Sensor;
+class ISensorEventConnection;
+
+class ISensorServer : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SensorServer);
+
+    virtual Vector<Sensor> getSensorList() = 0;
+    virtual sp<ISensorEventConnection> createSensorEventConnection() = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSensorServer : public BnInterface<ISensorServer>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_ISENSORSERVER_H
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
new file mode 100644
index 0000000..2de07b1
--- /dev/null
+++ b/include/gui/Sensor.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_GUI_SENSOR_H
+#define ANDROID_GUI_SENSOR_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Flattenable.h>
+
+#include <hardware/sensors.h>
+
+#include <android/sensor.h>
+
+// ----------------------------------------------------------------------------
+// Concrete types for the NDK
+struct ASensor { };
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class Parcel;
+
+// ----------------------------------------------------------------------------
+
+class Sensor : public ASensor, public Flattenable
+{
+public:
+    enum {
+        TYPE_ACCELEROMETER  = ASENSOR_TYPE_ACCELEROMETER,
+        TYPE_MAGNETIC_FIELD = ASENSOR_TYPE_MAGNETIC_FIELD,
+        TYPE_GYROSCOPE      = ASENSOR_TYPE_GYROSCOPE,
+        TYPE_LIGHT          = ASENSOR_TYPE_LIGHT,
+        TYPE_PROXIMITY      = ASENSOR_TYPE_PROXIMITY
+    };
+
+            Sensor();
+            Sensor(struct sensor_t const* hwSensor);
+    virtual ~Sensor();
+
+    const String8& getName() const;
+    const String8& getVendor() const;
+    int32_t getHandle() const;
+    int32_t getType() const;
+    float getMinValue() const;
+    float getMaxValue() const;
+    float getResolution() const;
+    float getPowerUsage() const;
+    int32_t getMinDelay() const;
+
+    // Flattenable interface
+    virtual size_t getFlattenedSize() const;
+    virtual size_t getFdCount() const;
+    virtual status_t flatten(void* buffer, size_t size,
+            int fds[], size_t count) const;
+    virtual status_t unflatten(void const* buffer, size_t size,
+            int fds[], size_t count);
+
+private:
+    String8 mName;
+    String8 mVendor;
+    int32_t mHandle;
+    int32_t mType;
+    float   mMinValue;
+    float   mMaxValue;
+    float   mResolution;
+    float   mPower;
+    int32_t mMinDelay;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_H
diff --git a/include/gui/SensorChannel.h b/include/gui/SensorChannel.h
new file mode 100644
index 0000000..bb54618
--- /dev/null
+++ b/include/gui/SensorChannel.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_GUI_SENSOR_CHANNEL_H
+#define ANDROID_GUI_SENSOR_CHANNEL_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+
+namespace android {
+// ----------------------------------------------------------------------------
+class Parcel;
+
+class SensorChannel : public RefBase
+{
+public:
+
+            SensorChannel();
+            SensorChannel(const Parcel& data);
+    virtual ~SensorChannel();
+
+    int getFd() const;
+    ssize_t write(void const* vaddr, size_t size);
+    ssize_t read(void* vaddr, size_t size);
+
+    status_t writeToParcel(Parcel* reply) const;
+
+private:
+    int mSendFd;
+    mutable int mReceiveFd;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_CHANNEL_H
diff --git a/include/gui/SensorEventQueue.h b/include/gui/SensorEventQueue.h
new file mode 100644
index 0000000..6581ae3
--- /dev/null
+++ b/include/gui/SensorEventQueue.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_SENSOR_EVENT_QUEUE_H
+#define ANDROID_SENSOR_EVENT_QUEUE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <gui/SensorChannel.h>
+
+// ----------------------------------------------------------------------------
+
+struct ALooper;
+struct ASensorEvent;
+
+// Concrete types for the NDK
+struct ASensorEventQueue {
+    ALooper* looper;
+};
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorEventConnection;
+class Sensor;
+class PollLoop;
+
+// ----------------------------------------------------------------------------
+
+class SensorEventQueue : public ASensorEventQueue, public RefBase
+{
+public:
+            SensorEventQueue(const sp<ISensorEventConnection>& connection);
+    virtual ~SensorEventQueue();
+    virtual void onFirstRef();
+
+    int getFd() const;
+    ssize_t write(ASensorEvent const* events, size_t numEvents);
+    ssize_t read(ASensorEvent* events, size_t numEvents);
+
+    status_t waitForEvent() const;
+    status_t wake() const;
+
+    status_t enableSensor(Sensor const* sensor) const;
+    status_t disableSensor(Sensor const* sensor) const;
+    status_t setEventRate(Sensor const* sensor, nsecs_t ns) const;
+
+    // these are here only to support SensorManager.java
+    status_t enableSensor(int32_t handle, int32_t us) const;
+    status_t disableSensor(int32_t handle) const;
+
+private:
+    sp<PollLoop> getPollLoop() const;
+    sp<ISensorEventConnection> mSensorEventConnection;
+    sp<SensorChannel> mSensorChannel;
+    mutable Mutex mLock;
+    mutable sp<PollLoop> mPollLoop;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SENSOR_EVENT_QUEUE_H
diff --git a/include/gui/SensorManager.h b/include/gui/SensorManager.h
new file mode 100644
index 0000000..e1b1a7b
--- /dev/null
+++ b/include/gui/SensorManager.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_GUI_SENSOR_MANAGER_H
+#define ANDROID_GUI_SENSOR_MANAGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Singleton.h>
+#include <utils/Vector.h>
+
+#include <gui/SensorEventQueue.h>
+
+// ----------------------------------------------------------------------------
+// Concrete types for the NDK
+struct ASensorManager { };
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+class ISensorServer;
+class Sensor;
+class SensorEventQueue;
+
+// ----------------------------------------------------------------------------
+
+class SensorManager : public ASensorManager, public Singleton<SensorManager>
+{
+public:
+    SensorManager();
+    ~SensorManager();
+
+    ssize_t getSensorList(Sensor const* const** list) const;
+    Sensor const* getDefaultSensor(int type);
+    sp<SensorEventQueue> createEventQueue();
+
+private:
+    sp<ISensorServer> mSensorServer;
+    Sensor const** mSensorList;
+    Vector<Sensor> mSensors;
+};
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_GUI_SENSOR_MANAGER_H
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9b5a1e0..d689667 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -43,24 +43,9 @@
  * unless they are in use by the server, which is only the case for the last 
  * dequeue-able buffer. When these various conditions are not met, the caller
  * waits until the condition is met.
- *
- * 
- * CAVEATS:
- * 
- * In the current implementation there are several limitations:
- * - buffers must be locked in the same order they've been dequeued
- * - buffers must be enqueued in the same order they've been locked
- * - dequeue() is not reentrant
- * - no error checks are done on the condition above
  * 
  */
 
-// When changing these values, the COMPILE_TIME_ASSERT at the end of this
-// file need to be updated.
-const unsigned int NUM_LAYERS_MAX  = 31;
-const unsigned int NUM_BUFFER_MAX  = 4;
-const unsigned int NUM_DISPLAY_MAX = 4;
-
 // ----------------------------------------------------------------------------
 
 class Region;
@@ -69,7 +54,6 @@
 
 // ----------------------------------------------------------------------------
 
-// should be 128 bytes (32 longs)
 class SharedBufferStack
 {
     friend class SharedClient;
@@ -78,22 +62,44 @@
     friend class SharedBufferServer;
 
 public:
-    struct FlatRegion { // 12 bytes
-        static const unsigned int NUM_RECT_MAX = 1;
-        uint32_t    count;
-        uint16_t    rects[4*NUM_RECT_MAX];
-    };
-    
+    // When changing these values, the COMPILE_TIME_ASSERT at the end of this
+    // file need to be updated.
+    static const unsigned int NUM_LAYERS_MAX  = 31;
+    static const unsigned int NUM_BUFFER_MAX  = 16;
+    static const unsigned int NUM_BUFFER_MIN  = 2;
+    static const unsigned int NUM_DISPLAY_MAX = 4;
+
     struct Statistics { // 4 longs
         typedef int32_t usecs_t;
         usecs_t  totalTime;
         usecs_t  reserved[3];
     };
+
+    struct SmallRect {
+        uint16_t l, t, r, b;
+    };
+
+    struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
+        static const unsigned int NUM_RECT_MAX = 5;
+        uint32_t    count;
+        SmallRect   rects[NUM_RECT_MAX];
+    };
+    
+    struct BufferData {
+        FlatRegion dirtyRegion;
+        SmallRect  crop;
+        uint8_t transform;
+        uint8_t reserved[3];
+    };
     
     SharedBufferStack();
     void init(int32_t identity);
     status_t setDirtyRegion(int buffer, const Region& reg);
+    status_t setCrop(int buffer, const Rect& reg);
+    status_t setTransform(int buffer, uint8_t transform);
     Region getDirtyRegion(int buffer) const;
+    Rect getCrop(int buffer) const;
+    uint32_t getTransform(int buffer) const;
 
     // these attributes are part of the conditions/updates
     volatile int32_t head;      // server's current front buffer
@@ -104,24 +110,25 @@
 
     // not part of the conditions
     volatile int32_t reallocMask;
+    volatile int8_t index[NUM_BUFFER_MAX];
 
     int32_t     identity;       // surface's identity (const)
-    int32_t     reserved32[9];
+    int32_t     token;          // surface's token (for debugging)
+    int32_t     reserved32[1];
     Statistics  stats;
-    FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
+    int32_t     reserved;
+    BufferData  buffers[NUM_BUFFER_MAX];     // 1024 bytes
 };
 
 // ----------------------------------------------------------------------------
 
-// 4 KB max
+// 32 KB max
 class SharedClient
 {
 public:
     SharedClient();
     ~SharedClient();
-
     status_t validate(size_t token) const;
-    uint32_t getIdentity(size_t token) const;
 
 private:
     friend class SharedBufferBase;
@@ -131,7 +138,7 @@
     // FIXME: this should be replaced by a lock-less primitive
     Mutex lock;
     Condition cv;
-    SharedBufferStack surfaces[ NUM_LAYERS_MAX ];
+    SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
 };
 
 // ============================================================================
@@ -139,18 +146,16 @@
 class SharedBufferBase
 {
 public:
-    SharedBufferBase(SharedClient* sharedClient, int surface, int num,
+    SharedBufferBase(SharedClient* sharedClient, int surface,
             int32_t identity);
     ~SharedBufferBase();
-    uint32_t getIdentity();
     status_t getStatus() const;
-    size_t getFrontBuffer() const;
+    int32_t getIdentity() const;
     String8 dump(char const* prefix) const;
 
 protected:
     SharedClient* const mSharedClient;
     SharedBufferStack* const mSharedStack;
-    const int mNumBuffers;
     const int mIdentity;
 
     friend struct Update;
@@ -160,61 +165,22 @@
         SharedBufferStack& stack;
         inline ConditionBase(SharedBufferBase* sbc) 
             : stack(*sbc->mSharedStack) { }
+        virtual ~ConditionBase() { };
+        virtual bool operator()() const = 0;
+        virtual const char* name() const = 0;
     };
+    status_t waitForCondition(const ConditionBase& condition);
 
     struct UpdateBase {
         SharedBufferStack& stack;
         inline UpdateBase(SharedBufferBase* sbb) 
             : stack(*sbb->mSharedStack) { }
     };
-
-    template <typename T>
-    status_t waitForCondition(T condition);
-
     template <typename T>
     status_t updateCondition(T update);
 };
 
 template <typename T>
-status_t SharedBufferBase::waitForCondition(T condition) 
-{
-    const SharedBufferStack& stack( *mSharedStack );
-    SharedClient& client( *mSharedClient );
-    const nsecs_t TIMEOUT = s2ns(1);
-    Mutex::Autolock _l(client.lock);
-    while ((condition()==false) &&
-            (stack.identity == mIdentity) &&
-            (stack.status == NO_ERROR))
-    {
-        status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
-        
-        // handle errors and timeouts
-        if (CC_UNLIKELY(err != NO_ERROR)) {
-            if (err == TIMED_OUT) {
-                if (condition()) {
-                    LOGE("waitForCondition(%s) timed out (identity=%d), "
-                        "but condition is true! We recovered but it "
-                        "shouldn't happen." , T::name(),
-                        stack.identity);
-                    break;
-                } else {
-                    LOGW("waitForCondition(%s) timed out "
-                        "(identity=%d, status=%d). "
-                        "CPU may be pegged. trying again.", T::name(),
-                        stack.identity, stack.status);
-                }
-            } else {
-                LOGE("waitForCondition(%s) error (%s) ",
-                        T::name(), strerror(-err));
-                return err;
-            }
-        }
-    }
-    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
-}
-
-
-template <typename T>
 status_t SharedBufferBase::updateCondition(T update) {
     SharedClient& client( *mSharedClient );
     Mutex::Autolock _l(client.lock);
@@ -238,19 +204,32 @@
     status_t queue(int buf);
     bool needNewBuffer(int buffer) const;
     status_t setDirtyRegion(int buffer, const Region& reg);
-    
+    status_t setCrop(int buffer, const Rect& reg);
+    status_t setTransform(int buffer, uint32_t transform);
+
+    class SetBufferCountCallback {
+        friend class SharedBufferClient;
+        virtual status_t operator()(int bufferCount) const = 0;
+    protected:
+        virtual ~SetBufferCountCallback() { }
+    };
+    status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
+
 private:
     friend struct Condition;
     friend struct DequeueCondition;
     friend struct LockCondition;
-    
-    int32_t computeTail() const;
 
     struct QueueUpdate : public UpdateBase {
         inline QueueUpdate(SharedBufferBase* sbb);
         inline ssize_t operator()();
     };
 
+    struct DequeueUpdate : public UpdateBase {
+        inline DequeueUpdate(SharedBufferBase* sbb);
+        inline ssize_t operator()();
+    };
+
     struct UndoDequeueUpdate : public UpdateBase {
         inline UndoDequeueUpdate(SharedBufferBase* sbb);
         inline ssize_t operator()();
@@ -260,25 +239,34 @@
 
     struct DequeueCondition : public ConditionBase {
         inline DequeueCondition(SharedBufferClient* sbc);
-        inline bool operator()();
-        static inline const char* name() { return "DequeueCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "DequeueCondition"; }
     };
 
     struct LockCondition : public ConditionBase {
         int buf;
         inline LockCondition(SharedBufferClient* sbc, int buf);
-        inline bool operator()();
-        static inline const char* name() { return "LockCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "LockCondition"; }
     };
 
+    int32_t computeTail() const;
+
+    mutable RWLock mLock;
+    int mNumBuffers;
+
     int32_t tail;
+    int32_t undoDequeueTail;
+    int32_t queued_head;
     // statistics...
-    nsecs_t mDequeueTime[NUM_BUFFER_MAX];
+    nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
 };
 
 // ----------------------------------------------------------------------------
 
-class SharedBufferServer : public SharedBufferBase
+class SharedBufferServer
+    : public SharedBufferBase,
+      public LightRefBase<SharedBufferServer>
 {
 public:
     SharedBufferServer(SharedClient* sharedClient, int surface, int num,
@@ -287,16 +275,75 @@
     ssize_t retireAndLock();
     status_t unlock(int buffer);
     void setStatus(status_t status);
-    status_t reallocate();
-    status_t assertReallocate(int buffer);
+    status_t reallocateAll();
+    status_t reallocateAllExcept(int buffer);
     int32_t getQueuedCount() const;
-    
     Region getDirtyRegion(int buffer) const;
+    Rect getCrop(int buffer) const;
+    uint32_t getTransform(int buffer) const;
+
+    status_t resize(int newNumBuffers);
 
     SharedBufferStack::Statistics getStats() const;
     
 
 private:
+    friend class LightRefBase<SharedBufferServer>;
+    ~SharedBufferServer();
+
+    /*
+     * BufferList is basically a fixed-capacity sorted-vector of
+     * unsigned 5-bits ints using a 32-bits int as storage.
+     * it has efficient iterators to find items in the list and not in the list.
+     */
+    class BufferList {
+        size_t mCapacity;
+        uint32_t mList;
+    public:
+        BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
+            : mCapacity(c), mList(0) { }
+        status_t add(int value);
+        status_t remove(int value);
+        uint32_t getMask() const { return mList; }
+
+        class const_iterator {
+            friend class BufferList;
+            uint32_t mask, curr;
+            const_iterator(uint32_t mask) :
+                mask(mask), curr(__builtin_clz(mask)) {
+            }
+        public:
+            inline bool operator == (const const_iterator& rhs) const {
+                return mask == rhs.mask;
+            }
+            inline bool operator != (const const_iterator& rhs) const {
+                return mask != rhs.mask;
+            }
+            inline int operator *() const { return curr; }
+            inline const const_iterator& operator ++() {
+                mask &= ~(1<<(31-curr));
+                curr = __builtin_clz(mask);
+                return *this;
+            }
+        };
+
+        inline const_iterator begin() const {
+            return const_iterator(mList);
+        }
+        inline const_iterator end() const   {
+            return const_iterator(0);
+        }
+        inline const_iterator free_begin() const {
+            uint32_t mask = (1 << (32-mCapacity)) - 1;
+            return const_iterator( ~(mList | mask) );
+        }
+    };
+
+    // this protects mNumBuffers and mBufferList
+    mutable RWLock mLock;
+    int mNumBuffers;
+    BufferList mBufferList;
+
     struct UnlockUpdate : public UpdateBase {
         const int lockedBuffer;
         inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
@@ -314,13 +361,6 @@
         inline StatusUpdate(SharedBufferBase* sbb, status_t status);
         inline ssize_t operator()();
     };
-
-    struct ReallocateCondition : public ConditionBase {
-        int buf;
-        inline ReallocateCondition(SharedBufferBase* sbb, int buf);
-        inline bool operator()();
-        static inline const char* name() { return "ReallocateCondition"; }
-    };
 };
 
 // ===========================================================================
@@ -344,13 +384,12 @@
     uint8_t         connected;
     uint8_t         reserved[3];
     uint32_t        pad[7];
-    display_cblk_t  displays[NUM_DISPLAY_MAX];
+    display_cblk_t  displays[SharedBufferStack::NUM_DISPLAY_MAX];
 };
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 472f759..ddbe03d 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -47,13 +47,30 @@
         POST_BUFFER, // one-way transaction
         CREATE_OVERLAY,
         REQUEST_BUFFER,
+        SET_BUFFER_COUNT,
     };
 
 public: 
     DECLARE_META_INTERFACE(Surface);
 
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; 
+    /*
+     * requests a new buffer for the given index. If w, h, or format are
+     * null the buffer is created with the parameters assigned to the
+     * surface it is bound to. Otherwise the buffer's parameters are
+     * set to those specified.
+     */
+    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
+
+    /*
+     * sets the number of buffers dequeuable for this surface.
+     */
+    virtual status_t setBufferCount(int bufferCount) = 0;
     
+    // ------------------------------------------------------------------------
+    // Deprecated...
+    // ------------------------------------------------------------------------
+
     class BufferHeap {
     public:
         enum {
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index d1e7785..dd44aa5 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -27,7 +27,7 @@
 
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -85,8 +85,11 @@
     /* create connection with surface flinger, requires
      * ACCESS_SURFACE_FLINGER permission
      */
+    virtual sp<ISurfaceComposerClient> createConnection() = 0;
 
-    virtual sp<ISurfaceFlingerClient> createConnection() = 0;
+    /* create a client connection with surface flinger
+     */
+    virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
 
     /* retrieve the control block */
     virtual sp<IMemoryHeap> getCblk() const = 0;
@@ -123,6 +126,7 @@
         // Java by ActivityManagerService.
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
+        CREATE_CLIENT_CONNECTION,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
         CLOSE_GLOBAL_TRANSACTION,
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
new file mode 100644
index 0000000..a1e9e04
--- /dev/null
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+#include <ui/PixelFormat.h>
+
+#include <surfaceflinger/ISurface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IMemoryHeap;
+
+typedef int32_t    ClientID;
+typedef int32_t    DisplayID;
+
+// ----------------------------------------------------------------------------
+
+class layer_state_t;
+
+class ISurfaceComposerClient : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SurfaceComposerClient);
+
+    struct surface_data_t {
+        int32_t             token;
+        int32_t             identity;
+        uint32_t            width;
+        uint32_t            height;
+        uint32_t            format;
+        status_t readFromParcel(const Parcel& parcel);
+        status_t writeToParcel(Parcel* parcel) const;
+    };
+
+    virtual sp<IMemoryHeap> getControlBlock() const = 0;
+    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const = 0;
+
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual sp<ISurface> createSurface( surface_data_t* data,
+                                        int pid,
+                                        const String8& name,
+                                        DisplayID display,
+                                        uint32_t w,
+                                        uint32_t h,
+                                        PixelFormat format,
+                                        uint32_t flags) = 0;
+
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual status_t    destroySurface(SurfaceID sid) = 0;
+
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual status_t    setState(int32_t count, const layer_state_t* states) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSurfaceComposerClient : public BnInterface<ISurfaceComposerClient>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceFlingerClient.h
deleted file mode 100644
index d257645..0000000
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include <binder/IInterface.h>
-
-#include <ui/PixelFormat.h>
-  
-#include <surfaceflinger/ISurface.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IMemoryHeap;
-
-typedef int32_t    ClientID;
-typedef int32_t    DisplayID;
-
-// ----------------------------------------------------------------------------
-
-class layer_state_t;
-
-class ISurfaceFlingerClient : public IInterface
-{
-public: 
-    DECLARE_META_INTERFACE(SurfaceFlingerClient);
-
-    struct surface_data_t {
-        int32_t             token;
-        int32_t             identity;
-        uint32_t            width;
-        uint32_t            height;
-        uint32_t            format;
-        status_t readFromParcel(const Parcel& parcel);
-        status_t writeToParcel(Parcel* parcel) const;
-    };
-    
-    virtual sp<IMemoryHeap> getControlBlock() const = 0;
-
-    virtual sp<ISurface> createSurface( surface_data_t* data,
-                                        int pid, 
-                                        const String8& name,
-                                        DisplayID display,
-                                        uint32_t w,
-                                        uint32_t h,
-                                        PixelFormat format,
-                                        uint32_t flags) = 0;
-                                    
-    virtual status_t    destroySurface(SurfaceID sid) = 0;
-
-    virtual status_t    setState(int32_t count, const layer_state_t* states) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 0279d84..7c5a39b 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
@@ -28,12 +29,15 @@
 #include <ui/egl/android_natives.h>
 
 #include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+
+#define ANDROID_VIEW_SURFACE_JNI_ID    "mNativeSurface"
 
 namespace android {
 
 // ---------------------------------------------------------------------------
 
+class GraphicBuffer;
 class GraphicBufferMapper;
 class IOMX;
 class Rect;
@@ -41,6 +45,7 @@
 class SurfaceComposerClient;
 class SharedClient;
 class SharedBufferClient;
+class SurfaceClient;
 
 // ---------------------------------------------------------------------------
 
@@ -56,7 +61,6 @@
     static bool isSameSurface(
             const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
         
-    SurfaceID   ID() const      { return mToken; }
     uint32_t    getFlags() const { return mFlags; }
     uint32_t    getIdentity() const { return mIdentity; }
 
@@ -104,7 +108,7 @@
     SurfaceControl(
             const sp<SurfaceComposerClient>& client,
             const sp<ISurface>& surface,
-            const ISurfaceFlingerClient::surface_data_t& data,
+            const ISurfaceComposerClient::surface_data_t& data,
             uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
 
     ~SurfaceControl();
@@ -128,7 +132,7 @@
 // ---------------------------------------------------------------------------
 
 class Surface 
-    : public EGLNativeBase<android_native_window_t, Surface, RefBase>
+    : public EGLNativeBase<ANativeWindow, Surface, RefBase>
 {
 public:
     struct SurfaceInfo {
@@ -141,17 +145,16 @@
         uint32_t    reserved[2];
     };
 
-    Surface(const Parcel& data);
+    static status_t writeToParcel(
+            const sp<Surface>& control, Parcel* parcel);
+
+    static sp<Surface> readFromParcel(const Parcel& data);
 
     static bool isValid(const sp<Surface>& surface) {
         return (surface != 0) && surface->isValid();
     }
 
-    static bool isSameSurface(
-            const sp<Surface>& lhs, const sp<Surface>& rhs);
-
     bool        isValid();
-    SurfaceID   ID() const          { return mToken; }
     uint32_t    getFlags() const    { return mFlags; }
     uint32_t    getIdentity() const { return mIdentity; }
 
@@ -163,44 +166,43 @@
     // setSwapRectangle() is intended to be used by GL ES clients
     void        setSwapRectangle(const Rect& r);
 
+
 private:
-    // can't be copied
-    Surface& operator = (Surface& rhs);
-    Surface(const Surface& rhs);
-
-    Surface(const sp<SurfaceControl>& control);
-    void init();
-     ~Surface();
-  
-    friend class SurfaceComposerClient;
-    friend class SurfaceControl;
-
-    
+    /*
+     * Android frameworks friends
+     * (eventually this should go away and be replaced by proper APIs)
+     */
     // camera and camcorder need access to the ISurface binder interface for preview
     friend class Camera;
     friend class MediaRecorder;
-    // mediaplayer needs access to ISurface for display
+    // MediaPlayer needs access to ISurface for display
     friend class MediaPlayer;
     friend class IOMX;
     // this is just to be able to write some unit tests
     friend class Test;
 
-    sp<SurfaceComposerClient> getClient() const;
-    sp<ISurface> getISurface() const;
+private:
+    friend class SurfaceComposerClient;
+    friend class SurfaceControl;
 
-    status_t getBufferLocked(int index, int usage);
-   
-           status_t validate() const;
+    // can't be copied
+    Surface& operator = (Surface& rhs);
+    Surface(const Surface& rhs);
 
-    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
-    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-    
-    static int setSwapInterval(android_native_window_t* window, int interval);
-    static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
-    static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
-    static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
-    static int query(android_native_window_t* window, int what, int* value);
-    static int perform(android_native_window_t* window, int operation, ...);
+    Surface(const sp<SurfaceControl>& control);
+    Surface(const Parcel& data, const sp<IBinder>& ref);
+    ~Surface();
+
+
+    /*
+     *  ANativeWindow hooks
+     */
+    static int setSwapInterval(ANativeWindow* window, int interval);
+    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
+    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int query(ANativeWindow* window, int what, int* value);
+    static int perform(ANativeWindow* window, int operation, ...);
 
     int dequeueBuffer(android_native_buffer_t** buffer);
     int lockBuffer(android_native_buffer_t* buffer);
@@ -208,44 +210,91 @@
     int query(int what, int* value);
     int perform(int operation, va_list args);
 
-    status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
-
     void dispatch_setUsage(va_list args);
     int  dispatch_connect(va_list args);
     int  dispatch_disconnect(va_list args);
+    int  dispatch_crop(va_list args);
+    int  dispatch_set_buffer_count(va_list args);
+    int  dispatch_set_buffers_geometry(va_list args);
+    int  dispatch_set_buffers_transform(va_list args);
     
     void setUsage(uint32_t reqUsage);
     int  connect(int api);
     int  disconnect(int api);
+    int  crop(Rect const* rect);
+    int  setBufferCount(int bufferCount);
+    int  setBuffersGeometry(int w, int h, int format);
+    int  setBuffersTransform(int transform);
 
-    uint32_t getUsage() const;
-    int      getConnectedApi() const;
+    /*
+     *  private stuff...
+     */
+    void init();
+    status_t validate() const;
+    sp<ISurface> getISurface() const;
+
+    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+
+    status_t getBufferLocked(int index,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+    int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
+
+    int getConnectedApi() const;
     
+    bool needNewBuffer(int bufIdx,
+            uint32_t *pWidth, uint32_t *pHeight,
+            uint32_t *pFormat, uint32_t *pUsage) const;
+
+    static void cleanCachedSurfaces();
+
+    class BufferInfo {
+        uint32_t mWidth;
+        uint32_t mHeight;
+        uint32_t mFormat;
+        uint32_t mUsage;
+        mutable uint32_t mDirty;
+        enum {
+            GEOMETRY = 0x01
+        };
+    public:
+        BufferInfo();
+        void set(uint32_t w, uint32_t h, uint32_t format);
+        void set(uint32_t usage);
+        void get(uint32_t *pWidth, uint32_t *pHeight,
+                uint32_t *pFormat, uint32_t *pUsage) const;
+        bool validateBuffer(const sp<GraphicBuffer>& buffer) const;
+    };
+
     // constants
-    sp<SurfaceComposerClient>   mClient;
+    GraphicBufferMapper&        mBufferMapper;
+    SurfaceClient&              mClient;
+    SharedBufferClient*         mSharedBufferClient;
+    status_t                    mInitCheck;
     sp<ISurface>                mSurface;
-    SurfaceID                   mToken;
     uint32_t                    mIdentity;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
-    GraphicBufferMapper&        mBufferMapper;
-    SharedBufferClient*         mSharedBufferClient;
 
     // protected by mSurfaceLock
     Rect                        mSwapRectangle;
-    uint32_t                    mUsage;
     int                         mConnected;
+    Rect                        mNextBufferCrop;
+    uint32_t                    mNextBufferTransform;
+    BufferInfo                  mBufferInfo;
     
     // protected by mSurfaceLock. These are also used from lock/unlock
     // but in that case, they must be called form the same thread.
-    sp<GraphicBuffer>           mBuffers[2];
     mutable Region              mDirtyRegion;
 
     // must be used from the lock/unlock thread
     sp<GraphicBuffer>           mLockedBuffer;
     sp<GraphicBuffer>           mPostedBuffer;
     mutable Region              mOldDirtyRegion;
-    bool                        mNeedFullUpdate;
+    bool                        mReserved;
+
+    // only used from dequeueBuffer()
+    Vector< sp<GraphicBuffer> > mBuffers;
 
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
@@ -254,6 +303,10 @@
     // Inherently thread-safe
     mutable Mutex               mSurfaceLock;
     mutable Mutex               mApiLock;
+
+    // A cache of Surface objects that have been deserialized into this process.
+    static Mutex sCachedSurfacesLock;
+    static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces;
 };
 
 }; // namespace android
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index 9d0f0cb..8773d71 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -22,8 +22,9 @@
 
 #include <binder/IBinder.h>
 
-#include <utils/SortedVector.h>
 #include <utils/RefBase.h>
+#include <utils/Singleton.h>
+#include <utils/SortedVector.h>
 #include <utils/threads.h>
 
 #include <ui/PixelFormat.h>
@@ -39,8 +40,26 @@
 class SharedClient;
 class ISurfaceComposer;
 class DisplayInfo;
+class surface_flinger_cblk_t;
 
-class SurfaceComposerClient : virtual public RefBase
+// ---------------------------------------------------------------------------
+
+class ComposerService : public Singleton<ComposerService>
+{
+    // these are constants
+    sp<ISurfaceComposer> mComposerService;
+    sp<IMemoryHeap> mServerCblkMemory;
+    surface_flinger_cblk_t volatile* mServerCblk;
+    ComposerService();
+    friend class Singleton<ComposerService>;
+public:
+    static sp<ISurfaceComposer> getComposerService();
+    static surface_flinger_cblk_t const volatile * getControlBlock();
+};
+
+// ---------------------------------------------------------------------------
+
+class SurfaceComposerClient : public RefBase
 {
 public:    
                 SurfaceComposerClient();
@@ -52,10 +71,6 @@
     // Return the connection of this client
     sp<IBinder> connection() const;
     
-    // Retrieve a client for an existing connection.
-    static sp<SurfaceComposerClient>
-                clientForConnection(const sp<IBinder>& conn);
-
     // Forcibly remove connection before all references have gone away.
     void        dispose();
 
@@ -123,13 +138,6 @@
     status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
             void* cookie = NULL, uint32_t flags = 0);
 
-private:
-    friend class Surface;
-    friend class SurfaceControl;
-    
-    SurfaceComposerClient(const sp<ISurfaceComposer>& sm, 
-            const sp<IBinder>& conn);
-
     status_t    hide(SurfaceID id);
     status_t    show(SurfaceID id, int32_t layer = -1);
     status_t    freeze(SurfaceID id);
@@ -142,32 +150,26 @@
     status_t    setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
     status_t    setPosition(SurfaceID id, int32_t x, int32_t y);
     status_t    setSize(SurfaceID id, uint32_t w, uint32_t h);
-    
-    void        signalServer();
-
     status_t    destroySurface(SurfaceID sid);
 
-    void        _init(const sp<ISurfaceComposer>& sm,
-                    const sp<ISurfaceFlingerClient>& conn);
-
-    inline layer_state_t*   _get_state_l(SurfaceID id);
-    layer_state_t*          _lockLayerState(SurfaceID id);
-    inline void             _unlockLayerState();
+private:
+    virtual void onFirstRef();
+    inline layer_state_t*   get_state_l(SurfaceID id);
+    layer_state_t*          lockLayerState(SurfaceID id);
+    inline void             unlockLayerState();
 
     mutable     Mutex                               mLock;
-                layer_state_t*                      mPrebuiltLayerState;
                 SortedVector<layer_state_t>         mStates;
                 int32_t                             mTransactionOpen;
+                layer_state_t*                      mPrebuiltLayerState;
 
                 // these don't need to be protected because they never change
                 // after assignment
                 status_t                    mStatus;
-                SharedClient*               mControl;
-                sp<IMemoryHeap>             mControlMemory;
-                sp<ISurfaceFlingerClient>   mClient;
-                sp<ISurfaceComposer>        mSignalServer;
+                sp<ISurfaceComposerClient>  mClient;
 };
 
+// ---------------------------------------------------------------------------
 }; // namespace android
 
 #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index a21bb49..25d5afb 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -18,6 +18,7 @@
 #ifndef _RUNTIME_EVENT_HUB_H
 #define _RUNTIME_EVENT_HUB_H
 
+#include <android/input.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Log.h>
@@ -27,6 +28,31 @@
 
 #include <linux/input.h>
 
+/* These constants are not defined in linux/input.h but they are part of the multitouch
+ * input protocol. */
+
+#define ABS_MT_TOUCH_MAJOR 0x30  /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR 0x31  /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR 0x32  /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR 0x33  /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION 0x34  /* Ellipse orientation */
+#define ABS_MT_POSITION_X 0x35   /* Center X ellipse position */
+#define ABS_MT_POSITION_Y 0x36   /* Center Y ellipse position */
+#define ABS_MT_TOOL_TYPE 0x37    /* Type of touching device (finger, pen, ...) */
+#define ABS_MT_BLOB_ID 0x38      /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39  /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a     /* Pressure on contact area */
+
+#define MT_TOOL_FINGER 0 /* Identifies a finger */
+#define MT_TOOL_PEN 1    /* Identifies a pen */
+
+#define SYN_MT_REPORT 2
+
+/* Convenience constants. */
+
+#define BTN_FIRST 0x100  // first button scancode
+#define BTN_LAST 0x15f   // last button scancode
+
 struct pollfd;
 
 namespace android {
@@ -34,73 +60,162 @@
 class KeyLayoutMap;
 
 /*
- * Grand Central Station for events.  With a single call to waitEvent()
- * you can wait for:
- *  - input events from the keypad of a real device
- *  - input events and meta-events (e.g. "quit") from the simulator
- *  - synthetic events from the runtime (e.g. "URL fetch completed")
- *  - real or forged "vsync" events
- *
- * Do not instantiate this class.  Instead, call startUp().
+ * A raw event as retrieved from the EventHub.
  */
-class EventHub : public RefBase
-{
+struct RawEvent {
+    nsecs_t when;
+    int32_t deviceId;
+    int32_t type;
+    int32_t scanCode;
+    int32_t keyCode;
+    int32_t value;
+    uint32_t flags;
+};
+
+/* Describes an absolute axis. */
+struct RawAbsoluteAxisInfo {
+    bool valid; // true if the information is valid, false otherwise
+
+    int32_t minValue;  // minimum value
+    int32_t maxValue;  // maximum value
+    int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
+    int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
+
+    inline int32_t getRange() { return maxValue - minValue; }
+
+    inline void clear() {
+        valid = false;
+        minValue = 0;
+        maxValue = 0;
+        flat = 0;
+        fuzz = 0;
+    }
+};
+
+/*
+ * Input device classes.
+ */
+enum {
+    /* The input device is a keyboard. */
+    INPUT_DEVICE_CLASS_KEYBOARD      = 0x00000001,
+
+    /* The input device is an alpha-numeric keyboard (not just a dial pad). */
+    INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,
+
+    /* The input device is a touchscreen (either single-touch or multi-touch). */
+    INPUT_DEVICE_CLASS_TOUCHSCREEN   = 0x00000004,
+
+    /* The input device is a trackball. */
+    INPUT_DEVICE_CLASS_TRACKBALL     = 0x00000008,
+
+    /* The input device is a multi-touch touchscreen. */
+    INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,
+
+    /* The input device is a directional pad. */
+    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,
+
+    /* The input device is a gamepad (implies keyboard). */
+    INPUT_DEVICE_CLASS_GAMEPAD       = 0x00000040,
+
+    /* The input device has switches. */
+    INPUT_DEVICE_CLASS_SWITCH        = 0x00000080,
+};
+
+/*
+ * Grand Central Station for events.
+ *
+ * The event hub aggregates input events received across all known input
+ * devices on the system, including devices that may be emulated by the simulator
+ * environment.  In addition, the event hub generates fake input events to indicate
+ * when devices are added or removed.
+ *
+ * The event hub provies a stream of input events (via the getEvent function).
+ * It also supports querying the current actual state of input devices such as identifying
+ * which keys are currently down.  Finally, the event hub keeps track of the capabilities of
+ * individual input devices, such as their class and the set of key codes that they support.
+ */
+class EventHubInterface : public virtual RefBase {
+protected:
+    EventHubInterface() { }
+    virtual ~EventHubInterface() { }
+
 public:
-    EventHub();
-    
-    status_t errorCheck() const;
-    
-    // bit fields for classes of devices.
-    enum {
-        CLASS_KEYBOARD      = 0x00000001,
-        CLASS_ALPHAKEY      = 0x00000002,
-        CLASS_TOUCHSCREEN   = 0x00000004,
-        CLASS_TRACKBALL     = 0x00000008,
-        CLASS_TOUCHSCREEN_MT= 0x00000010,
-        CLASS_DPAD          = 0x00000020
-    };
-    uint32_t getDeviceClasses(int32_t deviceId) const;
-    
-    String8 getDeviceName(int32_t deviceId) const;
-    
-    int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
-            int* outMaxValue, int* outFlat, int* outFuzz) const;
-        
-    int getSwitchState(int sw) const;
-    int getSwitchState(int32_t deviceId, int sw) const;
-    
-    int getScancodeState(int key) const;
-    int getScancodeState(int32_t deviceId, int key) const;
-    
-    int getKeycodeState(int key) const;
-    int getKeycodeState(int32_t deviceId, int key) const;
-    
-    status_t scancodeToKeycode(int32_t deviceId, int scancode,
-            int32_t* outKeycode, uint32_t* outFlags) const;
-
-    // exclude a particular device from opening
-    // this can be used to ignore input devices for sensors
-    void addExcludedDevice(const char* deviceName);
-
-    // special type codes when devices are added/removed.
+    // Synthetic raw event type codes produced when devices are added or removed.
     enum {
         DEVICE_ADDED = 0x10000000,
         DEVICE_REMOVED = 0x20000000
     };
-    
-    // examine key input devices for specific framework keycode support
-    bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags);
 
-    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
-            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
-            int32_t* outValue, nsecs_t* outWhen);
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
+
+    virtual String8 getDeviceName(int32_t deviceId) const = 0;
+
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const = 0;
+
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const = 0;
+
+    // exclude a particular device from opening
+    // this can be used to ignore input devices for sensors
+    virtual void addExcludedDevice(const char* deviceName) = 0;
+
+    /*
+     * Wait for the next event to become available and return it.
+     * After returning, the EventHub holds onto a wake lock until the next call to getEvent.
+     * This ensures that the device will not go to sleep while the event is being processed.
+     * If the device needs to remain awake longer than that, then the caller is responsible
+     * for taking care of it (say, by poking the power manager user activity timer).
+     */
+    virtual bool getEvent(RawEvent* outEvent) = 0;
+
+    /*
+     * Query current input state.
+     */
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
+
+    /*
+     * Examine key input devices for specific framework keycode support
+     */
+    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+            uint8_t* outFlags) const = 0;
+};
+
+class EventHub : public EventHubInterface
+{
+public:
+    EventHub();
+
+    status_t errorCheck() const;
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
+    
+    virtual String8 getDeviceName(int32_t deviceId) const;
+    
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const;
+
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const;
+
+    virtual void addExcludedDevice(const char* deviceName);
+
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
+
+    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags) const;
+
+    virtual bool getEvent(RawEvent* outEvent);
 
 protected:
     virtual ~EventHub();
     
 private:
     bool openPlatformInput(void);
-    int32_t convertDeviceKey_TI_P2(int code);
 
     int open_device(const char *device);
     int close_device(const char *device);
@@ -127,6 +242,12 @@
     device_t* getDevice(int32_t deviceId) const;
     bool hasKeycode(device_t* device, int keycode) const;
     
+    int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const;
+    int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const;
+    int32_t getSwitchStateLocked(device_t* device, int32_t sw) const;
+    bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags) const;
+
     // Protect all internal state.
     mutable Mutex   mLock;
     
@@ -152,8 +273,14 @@
 
     // device ids that report particular switches.
 #ifdef EV_SW
-    int32_t         mSwitches[SW_MAX+1];
+    int32_t         mSwitches[SW_MAX + 1];
 #endif
+
+    static const int INPUT_BUFFER_SIZE = 64;
+    struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
+    int32_t mInputBufferIndex;
+    int32_t mInputBufferCount;
+    int32_t mInputDeviceIndex;
 };
 
 }; // namespace android
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 8ea3ab9..0f4594f 100644
--- a/include/ui/FramebufferNativeWindow.h
+++ b/include/ui/FramebufferNativeWindow.h
@@ -43,7 +43,7 @@
 
 class FramebufferNativeWindow 
     : public EGLNativeBase<
-        android_native_window_t, 
+        ANativeWindow, 
         FramebufferNativeWindow, 
         LightRefBase<FramebufferNativeWindow> >
 {
@@ -59,12 +59,12 @@
 private:
     friend class LightRefBase<FramebufferNativeWindow>;    
     ~FramebufferNativeWindow(); // this class cannot be overloaded
-    static int setSwapInterval(android_native_window_t* window, int interval);
-    static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
-    static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
-    static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
-    static int query(android_native_window_t* window, int what, int* value);
-    static int perform(android_native_window_t* window, int operation, ...);
+    static int setSwapInterval(ANativeWindow* window, int interval);
+    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
+    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int query(ANativeWindow* window, int what, int* value);
+    static int perform(ANativeWindow* window, int operation, ...);
     
     framebuffer_device_t* fbDev;
     alloc_device_t* grDev;
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index e72b6b3..a3e85a9 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -93,10 +93,8 @@
     
     void setIndex(int index);
     int getIndex() const;
-    void setVerticalStride(uint32_t vstride);
-    uint32_t getVerticalStride() const;
 
-protected:
+private:
     virtual ~GraphicBuffer();
 
     enum {
@@ -105,8 +103,12 @@
         ownData   = 2,
     };
 
-    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
-    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+    inline const GraphicBufferMapper& getBufferMapper() const {
+        return mBufferMapper;
+    }
+    inline GraphicBufferMapper& getBufferMapper() {
+        return mBufferMapper;
+    }
     uint8_t mOwner;
 
 private:
@@ -134,7 +136,6 @@
 
     GraphicBufferMapper& mBufferMapper;
     ssize_t mInitCheck;
-    uint32_t mVStride;
     int mIndex;
 };
 
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 741d763..54b8236 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -73,9 +73,9 @@
     struct alloc_rec_t {
         uint32_t w;
         uint32_t h;
+        uint32_t s;
         PixelFormat format;
         uint32_t usage;
-        void* vaddr;
         size_t size;
     };
     
diff --git a/include/ui/Input.h b/include/ui/Input.h
new file mode 100644
index 0000000..b587e94
--- /dev/null
+++ b/include/ui/Input.h
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef _UI_INPUT_H
+#define _UI_INPUT_H
+
+/**
+ * Native input event structures.
+ */
+
+#include <android/input.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+/*
+ * Additional private constants not defined in ndk/ui/input.h.
+ */
+enum {
+    /*
+     * Private control to determine when an app is tracking a key sequence.
+     */
+    AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
+};
+
+/*
+ * Maximum number of pointers supported per motion event.
+ */
+#define MAX_POINTERS 10
+
+/*
+ * Declare a concrete type for the NDK's input event forward declaration.
+ */
+struct AInputEvent {
+    virtual ~AInputEvent() { }
+};
+
+/*
+ * Declare a concrete type for the NDK's input device forward declaration.
+ */
+struct AInputDevice {
+    virtual ~AInputDevice() { }
+};
+
+
+namespace android {
+
+/*
+ * Flags that flow alongside events in the input dispatch system to help with certain
+ * policy decisions such as waking from device sleep.
+ */
+enum {
+    /* These flags originate in RawEvents and are generally set in the key map. */
+
+    POLICY_FLAG_WAKE = 0x00000001,
+    POLICY_FLAG_WAKE_DROPPED = 0x00000002,
+    POLICY_FLAG_SHIFT = 0x00000004,
+    POLICY_FLAG_CAPS_LOCK = 0x00000008,
+    POLICY_FLAG_ALT = 0x00000010,
+    POLICY_FLAG_ALT_GR = 0x00000020,
+    POLICY_FLAG_MENU = 0x00000040,
+    POLICY_FLAG_LAUNCHER = 0x00000080,
+
+    POLICY_FLAG_RAW_MASK = 0x0000ffff,
+
+    /* These flags are set by the input dispatcher. */
+
+    // Indicates that the input event was injected.
+    POLICY_FLAG_INJECTED = 0x01000000,
+
+    /* These flags are set by the input reader policy as it intercepts each event. */
+
+    // Indicates that the screen was off when the event was received and the event
+    // should wake the device.
+    POLICY_FLAG_WOKE_HERE = 0x10000000,
+
+    // Indicates that the screen was dim when the event was received and the event
+    // should brighten the device.
+    POLICY_FLAG_BRIGHT_HERE = 0x20000000,
+};
+
+/*
+ * Describes the basic configuration of input devices that are present.
+ */
+struct InputConfiguration {
+    enum {
+        TOUCHSCREEN_UNDEFINED = 0,
+        TOUCHSCREEN_NOTOUCH = 1,
+        TOUCHSCREEN_STYLUS = 2,
+        TOUCHSCREEN_FINGER = 3
+    };
+
+    enum {
+        KEYBOARD_UNDEFINED = 0,
+        KEYBOARD_NOKEYS = 1,
+        KEYBOARD_QWERTY = 2,
+        KEYBOARD_12KEY = 3
+    };
+
+    enum {
+        NAVIGATION_UNDEFINED = 0,
+        NAVIGATION_NONAV = 1,
+        NAVIGATION_DPAD = 2,
+        NAVIGATION_TRACKBALL = 3,
+        NAVIGATION_WHEEL = 4
+    };
+
+    int32_t touchScreen;
+    int32_t keyboard;
+    int32_t navigation;
+};
+
+/*
+ * Pointer coordinate data.
+ */
+struct PointerCoords {
+    float x;
+    float y;
+    float pressure;
+    float size;
+    float touchMajor;
+    float touchMinor;
+    float toolMajor;
+    float toolMinor;
+    float orientation;
+};
+
+/*
+ * Input events.
+ */
+class InputEvent : public AInputEvent {
+public:
+    virtual ~InputEvent() { }
+
+    virtual int32_t getType() const = 0;
+
+    inline int32_t getDeviceId() const { return mDeviceId; }
+
+    inline int32_t getSource() const { return mSource; }
+    
+protected:
+    void initialize(int32_t deviceId, int32_t source);
+    void initialize(const InputEvent& from);
+
+private:
+    int32_t mDeviceId;
+    int32_t mSource;
+};
+
+/*
+ * Key events.
+ */
+class KeyEvent : public InputEvent {
+public:
+    virtual ~KeyEvent() { }
+
+    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    inline int32_t getKeyCode() const { return mKeyCode; }
+
+    inline int32_t getScanCode() const { return mScanCode; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline int32_t getRepeatCount() const { return mRepeatCount; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline nsecs_t getEventTime() const { return mEventTime; }
+
+    // Return true if this event may have a default action implementation.
+    static bool hasDefaultAction(int32_t keyCode);
+    bool hasDefaultAction() const;
+
+    // Return true if this event represents a system key.
+    static bool isSystemKey(int32_t keyCode);
+    bool isSystemKey() const;
+    
+    void initialize(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t keyCode,
+            int32_t scanCode,
+            int32_t metaState,
+            int32_t repeatCount,
+            nsecs_t downTime,
+            nsecs_t eventTime);
+    void initialize(const KeyEvent& from);
+
+private:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mKeyCode;
+    int32_t mScanCode;
+    int32_t mMetaState;
+    int32_t mRepeatCount;
+    nsecs_t mDownTime;
+    nsecs_t mEventTime;
+};
+
+/*
+ * Motion events.
+ */
+class MotionEvent : public InputEvent {
+public:
+    virtual ~MotionEvent() { }
+
+    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    inline int32_t getEdgeFlags() const { return mEdgeFlags; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline float getXOffset() const { return mXOffset; }
+
+    inline float getYOffset() const { return mYOffset; }
+
+    inline float getXPrecision() const { return mXPrecision; }
+
+    inline float getYPrecision() const { return mYPrecision; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline size_t getPointerCount() const { return mPointerIds.size(); }
+
+    inline int32_t getPointerId(size_t pointerIndex) const { return mPointerIds[pointerIndex]; }
+
+    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
+
+    inline float getRawX(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).x;
+    }
+
+    inline float getRawY(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).y;
+    }
+
+    inline float getX(size_t pointerIndex) const {
+        return getRawX(pointerIndex) + mXOffset;
+    }
+
+    inline float getY(size_t pointerIndex) const {
+        return getRawY(pointerIndex) + mYOffset;
+    }
+
+    inline float getPressure(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).pressure;
+    }
+
+    inline float getSize(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).size;
+    }
+
+    inline float getTouchMajor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).touchMajor;
+    }
+
+    inline float getTouchMinor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).touchMinor;
+    }
+
+    inline float getToolMajor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).toolMajor;
+    }
+
+    inline float getToolMinor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).toolMinor;
+    }
+
+    inline float getOrientation(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).orientation;
+    }
+
+    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
+
+    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
+        return mSampleEventTimes[historicalIndex];
+    }
+
+    inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
+    }
+
+    inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
+    }
+
+    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalRawX(pointerIndex, historicalIndex) + mXOffset;
+    }
+
+    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalRawY(pointerIndex, historicalIndex) + mYOffset;
+    }
+
+    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
+    }
+
+    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
+    }
+
+    inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor;
+    }
+
+    inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor;
+    }
+
+    inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor;
+    }
+
+    inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor;
+    }
+
+    inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation;
+    }
+
+    void initialize(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t edgeFlags,
+            int32_t metaState,
+            float xOffset,
+            float yOffset,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const int32_t* pointerIds,
+            const PointerCoords* pointerCoords);
+
+    void addSample(
+            nsecs_t eventTime,
+            const PointerCoords* pointerCoords);
+
+    void offsetLocation(float xOffset, float yOffset);
+
+    // Low-level accessors.
+    inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
+    inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
+    inline const PointerCoords* getSamplePointerCoords() const {
+            return mSamplePointerCoords.array();
+    }
+
+private:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mEdgeFlags;
+    int32_t mMetaState;
+    float mXOffset;
+    float mYOffset;
+    float mXPrecision;
+    float mYPrecision;
+    nsecs_t mDownTime;
+    Vector<int32_t> mPointerIds;
+    Vector<nsecs_t> mSampleEventTimes;
+    Vector<PointerCoords> mSamplePointerCoords;
+
+    inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
+        return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+    }
+
+    inline const PointerCoords& getHistoricalPointerCoords(
+            size_t pointerIndex, size_t historicalIndex) const {
+        return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+    }
+};
+
+/*
+ * Input event factory.
+ */
+class InputEventFactoryInterface {
+protected:
+    virtual ~InputEventFactoryInterface() { }
+
+public:
+    InputEventFactoryInterface() { }
+
+    virtual KeyEvent* createKeyEvent() = 0;
+    virtual MotionEvent* createMotionEvent() = 0;
+};
+
+/*
+ * A simple input event factory implementation that uses a single preallocated instance
+ * of each type of input event that are reused for each request.
+ */
+class PreallocatedInputEventFactory : public InputEventFactoryInterface {
+public:
+    PreallocatedInputEventFactory() { }
+    virtual ~PreallocatedInputEventFactory() { }
+
+    virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
+    virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
+
+private:
+    KeyEvent mKeyEvent;
+    MotionEvent mMotionEvent;
+};
+
+/*
+ * Describes the characteristics and capabilities of an input device.
+ */
+class InputDeviceInfo {
+public:
+    InputDeviceInfo();
+    InputDeviceInfo(const InputDeviceInfo& other);
+    ~InputDeviceInfo();
+
+    struct MotionRange {
+        float min;
+        float max;
+        float flat;
+        float fuzz;
+    };
+
+    void initialize(int32_t id, const String8& name);
+
+    inline int32_t getId() const { return mId; }
+    inline const String8 getName() const { return mName; }
+    inline uint32_t getSources() const { return mSources; }
+
+    const MotionRange* getMotionRange(int32_t rangeType) const;
+
+    void addSource(uint32_t source);
+    void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
+    void addMotionRange(int32_t rangeType, const MotionRange& range);
+
+    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
+    inline int32_t getKeyboardType() const { return mKeyboardType; }
+
+    inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+        return mMotionRanges;
+    }
+
+private:
+    int32_t mId;
+    String8 mName;
+    uint32_t mSources;
+    int32_t mKeyboardType;
+
+    KeyedVector<int32_t, MotionRange> mMotionRanges;
+};
+
+
+} // namespace android
+
+#endif // _UI_INPUT_H
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
new file mode 100644
index 0000000..f00f2db
--- /dev/null
+++ b/include/ui/InputDispatcher.h
@@ -0,0 +1,705 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef _UI_INPUT_DISPATCHER_H
+#define _UI_INPUT_DISPATCHER_H
+
+#include <ui/Input.h>
+#include <ui/InputTransport.h>
+#include <utils/KeyedVector.h>
+#include <utils/Vector.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/PollLoop.h>
+#include <utils/Pool.h>
+
+#include <stddef.h>
+#include <unistd.h>
+
+
+namespace android {
+
+/*
+ * Constants used to report the outcome of input event injection.
+ */
+enum {
+    /* (INTERNAL USE ONLY) Specifies that injection is pending and its outcome is unknown. */
+    INPUT_EVENT_INJECTION_PENDING = -1,
+
+    /* Injection succeeded. */
+    INPUT_EVENT_INJECTION_SUCCEEDED = 0,
+
+    /* Injection failed because the injector did not have permission to inject
+     * into the application with input focus. */
+    INPUT_EVENT_INJECTION_PERMISSION_DENIED = 1,
+
+    /* Injection failed because there were no available input targets. */
+    INPUT_EVENT_INJECTION_FAILED = 2,
+
+    /* Injection failed due to a timeout. */
+    INPUT_EVENT_INJECTION_TIMED_OUT = 3
+};
+
+/*
+ * Constants used to determine the input event injection synchronization mode.
+ */
+enum {
+    /* Injection is asynchronous and is assumed always to be successful. */
+    INPUT_EVENT_INJECTION_SYNC_NONE = 0,
+
+    /* Waits for previous events to be dispatched so that the input dispatcher can determine
+     * whether input event injection willbe permitted based on the current input focus.
+     * Does not wait for the input event to finish processing. */
+    INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_RESULT = 1,
+
+    /* Waits for the input event to be completely processed. */
+    INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED = 2,
+};
+
+
+/*
+ * An input target specifies how an input event is to be dispatched to a particular window
+ * including the window's input channel, control flags, a timeout, and an X / Y offset to
+ * be added to input event coordinates to compensate for the absolute position of the
+ * window area.
+ */
+struct InputTarget {
+    enum {
+        /* This flag indicates that subsequent event delivery should be held until the
+         * current event is delivered to this target or a timeout occurs. */
+        FLAG_SYNC = 0x01,
+
+        /* This flag indicates that a MotionEvent with AMOTION_EVENT_ACTION_DOWN falls outside
+         * of the area of this target and so should instead be delivered as an
+         * AMOTION_EVENT_ACTION_OUTSIDE to this target. */
+        FLAG_OUTSIDE = 0x02,
+
+        /* This flag indicates that a KeyEvent or MotionEvent is being canceled.
+         * In the case of a key event, it should be delivered with flag
+         * AKEY_EVENT_FLAG_CANCELED set.
+         * In the case of a motion event, it should be delivered with action
+         * AMOTION_EVENT_ACTION_CANCEL instead. */
+        FLAG_CANCEL = 0x04,
+
+        /* This flag indicates that the target of a MotionEvent is partly or wholly
+         * obscured by another visible window above it.  The motion event should be
+         * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
+        FLAG_WINDOW_IS_OBSCURED = 0x08,
+    };
+
+    // The input channel to be targeted.
+    sp<InputChannel> inputChannel;
+
+    // Flags for the input target.
+    int32_t flags;
+
+    // The timeout for event delivery to this target in nanoseconds.  Or -1 if none.
+    nsecs_t timeout;
+
+    // The x and y offset to add to a MotionEvent as it is delivered.
+    // (ignored for KeyEvents)
+    float xOffset, yOffset;
+};
+
+
+/*
+ * Input dispatcher policy interface.
+ *
+ * The input reader policy is used by the input reader to interact with the Window Manager
+ * and other system components.
+ *
+ * The actual implementation is partially supported by callbacks into the DVM
+ * via JNI.  This interface is also mocked in the unit tests.
+ */
+class InputDispatcherPolicyInterface : public virtual RefBase {
+protected:
+    InputDispatcherPolicyInterface() { }
+    virtual ~InputDispatcherPolicyInterface() { }
+
+public:
+    /* Notifies the system that a configuration change has occurred. */
+    virtual void notifyConfigurationChanged(nsecs_t when) = 0;
+
+    /* Notifies the system that an input channel is unrecoverably broken. */
+    virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) = 0;
+
+    /* Notifies the system that an input channel is not responding.
+     * Returns true and a new timeout value if the dispatcher should keep waiting.
+     * Otherwise returns false. */
+    virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
+            nsecs_t& outNewTimeout) = 0;
+
+    /* Notifies the system that an input channel recovered from ANR. */
+    virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) = 0;
+
+    /* Gets the key repeat initial timeout or -1 if automatic key repeating is disabled. */
+    virtual nsecs_t getKeyRepeatTimeout() = 0;
+
+    /* Gets the key repeat inter-key delay. */
+    virtual nsecs_t getKeyRepeatDelay() = 0;
+
+    /* Waits for key event input targets to become available.
+     * If the event is being injected, injectorPid and injectorUid should specify the
+     * process id and used id of the injecting application, otherwise they should both
+     * be -1.
+     * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
+    virtual int32_t waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
+            int32_t injectorPid, int32_t injectorUid,
+            Vector<InputTarget>& outTargets) = 0;
+
+    /* Waits for motion event targets to become available.
+     * If the event is being injected, injectorPid and injectorUid should specify the
+     * process id and used id of the injecting application, otherwise they should both
+     * be -1.
+     * Returns one of the INPUT_EVENT_INJECTION_XXX constants. */
+    virtual int32_t waitForMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
+            int32_t injectorPid, int32_t injectorUid,
+            Vector<InputTarget>& outTargets) = 0;
+
+    /* Gets the maximum suggested event delivery rate per second.
+     * This value is used to throttle motion event movement actions on a per-device
+     * basis.  It is not intended to be a hard limit.
+     */
+    virtual int32_t getMaxEventsPerSecond() = 0;
+};
+
+
+/* Notifies the system about input events generated by the input reader.
+ * The dispatcher is expected to be mostly asynchronous. */
+class InputDispatcherInterface : public virtual RefBase {
+protected:
+    InputDispatcherInterface() { }
+    virtual ~InputDispatcherInterface() { }
+
+public:
+    /* Runs a single iteration of the dispatch loop.
+     * Nominally processes one queued event, a timeout, or a response from an input consumer.
+     *
+     * This method should only be called on the input dispatcher thread.
+     */
+    virtual void dispatchOnce() = 0;
+
+    /* Notifies the dispatcher about new events.
+     *
+     * These methods should only be called on the input reader thread.
+     */
+    virtual void notifyConfigurationChanged(nsecs_t eventTime) = 0;
+    virtual void notifyAppSwitchComing(nsecs_t eventTime) = 0;
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
+            int32_t scanCode, int32_t metaState, nsecs_t downTime) = 0;
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+            uint32_t policyFlags, int32_t action, int32_t flags,
+            int32_t metaState, int32_t edgeFlags,
+            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+            float xPrecision, float yPrecision, nsecs_t downTime) = 0;
+
+    /* Injects an input event and optionally waits for sync.
+     * The synchronization mode determines whether the method blocks while waiting for
+     * input injection to proceed.
+     * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
+
+    /* Preempts input dispatch in progress by making pending synchronous
+     * dispatches asynchronous instead.  This method is generally called during a focus
+     * transition from one application to the next so as to enable the new application
+     * to start receiving input as soon as possible without having to wait for the
+     * old application to finish up.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void preemptInputDispatch() = 0;
+
+    /* Registers or unregister input channels that may be used as targets for input events.
+     *
+     * These methods may be called on any thread (usually by the input manager).
+     */
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
+};
+
+/* Dispatches events to input targets.  Some functions of the input dispatcher, such as
+ * identifying input targets, are controlled by a separate policy object.
+ *
+ * IMPORTANT INVARIANT:
+ *     Because the policy can potentially block or cause re-entrance into the input dispatcher,
+ *     the input dispatcher never calls into the policy while holding its internal locks.
+ *     The implementation is also carefully designed to recover from scenarios such as an
+ *     input channel becoming unregistered while identifying input targets or processing timeouts.
+ *
+ *     Methods marked 'Locked' must be called with the lock acquired.
+ *
+ *     Methods marked 'LockedInterruptible' must be called with the lock acquired but
+ *     may during the course of their execution release the lock, call into the policy, and
+ *     then reacquire the lock.  The caller is responsible for recovering gracefully.
+ *
+ *     A 'LockedInterruptible' method may called a 'Locked' method, but NOT vice-versa.
+ */
+class InputDispatcher : public InputDispatcherInterface {
+protected:
+    virtual ~InputDispatcher();
+
+public:
+    explicit InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy);
+
+    virtual void dispatchOnce();
+
+    virtual void notifyConfigurationChanged(nsecs_t eventTime);
+    virtual void notifyAppSwitchComing(nsecs_t eventTime);
+    virtual void notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode,
+            int32_t scanCode, int32_t metaState, nsecs_t downTime);
+    virtual void notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+            uint32_t policyFlags, int32_t action, int32_t flags,
+            int32_t metaState, int32_t edgeFlags,
+            uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+            float xPrecision, float yPrecision, nsecs_t downTime);
+
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
+
+    virtual void preemptInputDispatch();
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+private:
+    template <typename T>
+    struct Link {
+        T* next;
+        T* prev;
+    };
+
+    struct EventEntry : Link<EventEntry> {
+        enum {
+            TYPE_SENTINEL,
+            TYPE_CONFIGURATION_CHANGED,
+            TYPE_KEY,
+            TYPE_MOTION
+        };
+
+        int32_t refCount;
+        int32_t type;
+        nsecs_t eventTime;
+
+        int32_t injectionResult;  // initially INPUT_EVENT_INJECTION_PENDING
+        bool    injectionIsAsync; // set to true if injection is not waiting for the result
+        int32_t injectorPid;      // -1 if not injected
+        int32_t injectorUid;      // -1 if not injected
+
+        bool dispatchInProgress; // initially false, set to true while dispatching
+        int32_t pendingSyncDispatches; // the number of synchronous dispatches in progress
+
+        inline bool isInjected() { return injectorPid >= 0; }
+    };
+
+    struct ConfigurationChangedEntry : EventEntry {
+    };
+
+    struct KeyEntry : EventEntry {
+        int32_t deviceId;
+        int32_t source;
+        uint32_t policyFlags;
+        int32_t action;
+        int32_t flags;
+        int32_t keyCode;
+        int32_t scanCode;
+        int32_t metaState;
+        int32_t repeatCount;
+        nsecs_t downTime;
+    };
+
+    struct MotionSample {
+        MotionSample* next;
+
+        nsecs_t eventTime;
+        PointerCoords pointerCoords[MAX_POINTERS];
+    };
+
+    struct MotionEntry : EventEntry {
+        int32_t deviceId;
+        int32_t source;
+        uint32_t policyFlags;
+        int32_t action;
+        int32_t flags;
+        int32_t metaState;
+        int32_t edgeFlags;
+        float xPrecision;
+        float yPrecision;
+        nsecs_t downTime;
+        uint32_t pointerCount;
+        int32_t pointerIds[MAX_POINTERS];
+
+        // Linked list of motion samples associated with this motion event.
+        MotionSample firstSample;
+        MotionSample* lastSample;
+
+        uint32_t countSamples() const;
+    };
+
+    // Tracks the progress of dispatching a particular event to a particular connection.
+    struct DispatchEntry : Link<DispatchEntry> {
+        EventEntry* eventEntry; // the event to dispatch
+        int32_t targetFlags;
+        float xOffset;
+        float yOffset;
+        nsecs_t timeout;
+
+        // True if dispatch has started.
+        bool inProgress;
+
+        // For motion events:
+        //   Pointer to the first motion sample to dispatch in this cycle.
+        //   Usually NULL to indicate that the list of motion samples begins at
+        //   MotionEntry::firstSample.  Otherwise, some samples were dispatched in a previous
+        //   cycle and this pointer indicates the location of the first remainining sample
+        //   to dispatch during the current cycle.
+        MotionSample* headMotionSample;
+        //   Pointer to a motion sample to dispatch in the next cycle if the dispatcher was
+        //   unable to send all motion samples during this cycle.  On the next cycle,
+        //   headMotionSample will be initialized to tailMotionSample and tailMotionSample
+        //   will be set to NULL.
+        MotionSample* tailMotionSample;
+
+        inline bool isSyncTarget() {
+            return targetFlags & InputTarget::FLAG_SYNC;
+        }
+    };
+
+    // A command entry captures state and behavior for an action to be performed in the
+    // dispatch loop after the initial processing has taken place.  It is essentially
+    // a kind of continuation used to postpone sensitive policy interactions to a point
+    // in the dispatch loop where it is safe to release the lock (generally after finishing
+    // the critical parts of the dispatch cycle).
+    //
+    // The special thing about commands is that they can voluntarily release and reacquire
+    // the dispatcher lock at will.  Initially when the command starts running, the
+    // dispatcher lock is held.  However, if the command needs to call into the policy to
+    // do some work, it can release the lock, do the work, then reacquire the lock again
+    // before returning.
+    //
+    // This mechanism is a bit clunky but it helps to preserve the invariant that the dispatch
+    // never calls into the policy while holding its lock.
+    //
+    // Commands are implicitly 'LockedInterruptible'.
+    struct CommandEntry;
+    typedef void (InputDispatcher::*Command)(CommandEntry* commandEntry);
+
+    class Connection;
+    struct CommandEntry : Link<CommandEntry> {
+        CommandEntry();
+        ~CommandEntry();
+
+        Command command;
+
+        // parameters for the command (usage varies by command)
+        sp<Connection> connection;
+    };
+
+    // Generic queue implementation.
+    template <typename T>
+    struct Queue {
+        T head;
+        T tail;
+
+        inline Queue() {
+            head.prev = NULL;
+            head.next = & tail;
+            tail.prev = & head;
+            tail.next = NULL;
+        }
+
+        inline bool isEmpty() {
+            return head.next == & tail;
+        }
+
+        inline void enqueueAtTail(T* entry) {
+            T* last = tail.prev;
+            last->next = entry;
+            entry->prev = last;
+            entry->next = & tail;
+            tail.prev = entry;
+        }
+
+        inline void enqueueAtHead(T* entry) {
+            T* first = head.next;
+            head.next = entry;
+            entry->prev = & head;
+            entry->next = first;
+            first->prev = entry;
+        }
+
+        inline void dequeue(T* entry) {
+            entry->prev->next = entry->next;
+            entry->next->prev = entry->prev;
+        }
+
+        inline T* dequeueAtHead() {
+            T* first = head.next;
+            dequeue(first);
+            return first;
+        }
+    };
+
+    /* Allocates queue entries and performs reference counting as needed. */
+    class Allocator {
+    public:
+        Allocator();
+
+        ConfigurationChangedEntry* obtainConfigurationChangedEntry(nsecs_t eventTime);
+        KeyEntry* obtainKeyEntry(nsecs_t eventTime,
+                int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+                int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+                int32_t repeatCount, nsecs_t downTime);
+        MotionEntry* obtainMotionEntry(nsecs_t eventTime,
+                int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+                int32_t flags, int32_t metaState, int32_t edgeFlags,
+                float xPrecision, float yPrecision,
+                nsecs_t downTime, uint32_t pointerCount,
+                const int32_t* pointerIds, const PointerCoords* pointerCoords);
+        DispatchEntry* obtainDispatchEntry(EventEntry* eventEntry);
+        CommandEntry* obtainCommandEntry(Command command);
+
+        void releaseEventEntry(EventEntry* entry);
+        void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
+        void releaseKeyEntry(KeyEntry* entry);
+        void releaseMotionEntry(MotionEntry* entry);
+        void releaseDispatchEntry(DispatchEntry* entry);
+        void releaseCommandEntry(CommandEntry* entry);
+
+        void appendMotionSample(MotionEntry* motionEntry,
+                nsecs_t eventTime, const PointerCoords* pointerCoords);
+
+    private:
+        Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
+        Pool<KeyEntry> mKeyEntryPool;
+        Pool<MotionEntry> mMotionEntryPool;
+        Pool<MotionSample> mMotionSamplePool;
+        Pool<DispatchEntry> mDispatchEntryPool;
+        Pool<CommandEntry> mCommandEntryPool;
+
+        void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
+    };
+
+    /* Manages the dispatch state associated with a single input channel. */
+    class Connection : public RefBase {
+    protected:
+        virtual ~Connection();
+
+    public:
+        enum Status {
+            // Everything is peachy.
+            STATUS_NORMAL,
+            // An unrecoverable communication error has occurred.
+            STATUS_BROKEN,
+            // The client is not responding.
+            STATUS_NOT_RESPONDING,
+            // The input channel has been unregistered.
+            STATUS_ZOMBIE
+        };
+
+        Status status;
+        sp<InputChannel> inputChannel;
+        InputPublisher inputPublisher;
+        Queue<DispatchEntry> outboundQueue;
+        nsecs_t nextTimeoutTime; // next timeout time (LONG_LONG_MAX if none)
+
+        nsecs_t lastEventTime; // the time when the event was originally captured
+        nsecs_t lastDispatchTime; // the time when the last event was dispatched
+        nsecs_t lastANRTime; // the time when the last ANR was recorded
+
+        explicit Connection(const sp<InputChannel>& inputChannel);
+
+        inline const char* getInputChannelName() const { return inputChannel->getName().string(); }
+
+        const char* getStatusLabel() const;
+
+        // Finds a DispatchEntry in the outbound queue associated with the specified event.
+        // Returns NULL if not found.
+        DispatchEntry* findQueuedDispatchEntryForEvent(const EventEntry* eventEntry) const;
+
+        // Determine whether this connection has a pending synchronous dispatch target.
+        // Since there can only ever be at most one such target at a time, if there is one,
+        // it must be at the tail because nothing else can be enqueued after it.
+        inline bool hasPendingSyncTarget() {
+            return ! outboundQueue.isEmpty() && outboundQueue.tail.prev->isSyncTarget();
+        }
+
+        // Gets the time since the current event was originally obtained from the input driver.
+        inline double getEventLatencyMillis(nsecs_t currentTime) {
+            return (currentTime - lastEventTime) / 1000000.0;
+        }
+
+        // Gets the time since the current event entered the outbound dispatch queue.
+        inline double getDispatchLatencyMillis(nsecs_t currentTime) {
+            return (currentTime - lastDispatchTime) / 1000000.0;
+        }
+
+        // Gets the time since the current event ANR was declared, if applicable.
+        inline double getANRLatencyMillis(nsecs_t currentTime) {
+            return (currentTime - lastANRTime) / 1000000.0;
+        }
+
+        status_t initialize();
+
+        void setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout);
+    };
+
+    sp<InputDispatcherPolicyInterface> mPolicy;
+
+    Mutex mLock;
+
+    Allocator mAllocator;
+    sp<PollLoop> mPollLoop;
+
+    Queue<EventEntry> mInboundQueue;
+    Queue<CommandEntry> mCommandQueue;
+
+    // All registered connections mapped by receive pipe file descriptor.
+    KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
+
+    ssize_t getConnectionIndex(const sp<InputChannel>& inputChannel);
+
+    // Active connections are connections that have a non-empty outbound queue.
+    // We don't use a ref-counted pointer here because we explicitly abort connections
+    // during unregistration which causes the connection's outbound queue to be cleared
+    // and the connection itself to be deactivated.
+    Vector<Connection*> mActiveConnections;
+
+    // List of connections that have timed out.  Only used by dispatchOnce()
+    // We don't use a ref-counted pointer here because it is not possible for a connection
+    // to be unregistered while processing timed out connections since we hold the lock for
+    // the duration.
+    Vector<Connection*> mTimedOutConnections;
+
+    // Preallocated key and motion event objects used only to ask the input dispatcher policy
+    // for the targets of an event that is to be dispatched.
+    KeyEvent mReusableKeyEvent;
+    MotionEvent mReusableMotionEvent;
+
+    // The input targets that were most recently identified for dispatch.
+    // If there is a synchronous event dispatch in progress, the current input targets will
+    // remain unchanged until the dispatch has completed or been aborted.
+    Vector<InputTarget> mCurrentInputTargets;
+    bool mCurrentInputTargetsValid; // false while targets are being recomputed
+
+    // Event injection and synchronization.
+    Condition mInjectionResultAvailableCondition;
+    EventEntry* createEntryFromInputEventLocked(const InputEvent* event);
+    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
+
+    Condition mInjectionSyncFinishedCondition;
+    void decrementPendingSyncDispatchesLocked(EventEntry* entry);
+
+    // Throttling state.
+    struct ThrottleState {
+        nsecs_t minTimeBetweenEvents;
+
+        nsecs_t lastEventTime;
+        int32_t lastDeviceId;
+        uint32_t lastSource;
+
+        uint32_t originalSampleCount; // only collected during debugging
+    } mThrottleState;
+
+    // Key repeat tracking.
+    // XXX Move this up to the input reader instead.
+    struct KeyRepeatState {
+        KeyEntry* lastKeyEntry; // or null if no repeat
+        nsecs_t nextRepeatTime;
+    } mKeyRepeatState;
+
+    void resetKeyRepeatLocked();
+
+    // Deferred command processing.
+    bool runCommandsLockedInterruptible();
+    CommandEntry* postCommandLocked(Command command);
+
+    // Process events that have just been dequeued from the head of the input queue.
+    void processConfigurationChangedLockedInterruptible(
+            nsecs_t currentTime, ConfigurationChangedEntry* entry);
+    void processKeyLockedInterruptible(
+            nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout);
+    void processKeyRepeatLockedInterruptible(
+            nsecs_t currentTime, nsecs_t keyRepeatTimeout);
+    void processMotionLockedInterruptible(
+            nsecs_t currentTime, MotionEntry* entry);
+
+    // Identify input targets for an event and dispatch to them.
+    void identifyInputTargetsAndDispatchKeyLockedInterruptible(
+            nsecs_t currentTime, KeyEntry* entry);
+    void identifyInputTargetsAndDispatchMotionLockedInterruptible(
+            nsecs_t currentTime, MotionEntry* entry);
+    void dispatchEventToCurrentInputTargetsLocked(
+            nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
+
+    // Manage the dispatch cycle for a single connection.
+    // These methods are deliberately not Interruptible because doing all of the work
+    // with the mutex held makes it easier to ensure that connection invariants are maintained.
+    // If needed, the methods post commands to run later once the critical bits are done.
+    void prepareDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
+            EventEntry* eventEntry, const InputTarget* inputTarget,
+            bool resumeWithAppendedMotionSample);
+    void startDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+    void finishDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+    void timeoutDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+    void resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
+            const sp<Connection>& connection, nsecs_t newTimeout);
+    void abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
+            bool broken);
+    static bool handleReceiveCallback(int receiveFd, int events, void* data);
+
+    // Add or remove a connection to the mActiveConnections vector.
+    void activateConnectionLocked(Connection* connection);
+    void deactivateConnectionLocked(Connection* connection);
+
+    // Interesting events that we might like to log or tell the framework about.
+    void onDispatchCycleStartedLocked(
+            nsecs_t currentTime, const sp<Connection>& connection);
+    void onDispatchCycleFinishedLocked(
+            nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR);
+    void onDispatchCycleANRLocked(
+            nsecs_t currentTime, const sp<Connection>& connection);
+    void onDispatchCycleBrokenLocked(
+            nsecs_t currentTime, const sp<Connection>& connection);
+
+    // Outbound policy interactions.
+    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
+    void doNotifyInputChannelANRLockedInterruptible(CommandEntry* commandEntry);
+    void doNotifyInputChannelRecoveredFromANRLockedInterruptible(CommandEntry* commandEntry);
+};
+
+/* Enqueues and dispatches input events, endlessly. */
+class InputDispatcherThread : public Thread {
+public:
+    explicit InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher);
+    ~InputDispatcherThread();
+
+private:
+    virtual bool threadLoop();
+
+    sp<InputDispatcherInterface> mDispatcher;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_DISPATCHER_PRIV_H
diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h
new file mode 100644
index 0000000..4012c69
--- /dev/null
+++ b/include/ui/InputManager.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef _UI_INPUT_MANAGER_H
+#define _UI_INPUT_MANAGER_H
+
+/**
+ * Native input manager.
+ */
+
+#include <ui/EventHub.h>
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+class InputChannel;
+
+class InputReaderInterface;
+class InputReaderPolicyInterface;
+class InputReaderThread;
+
+class InputDispatcherInterface;
+class InputDispatcherPolicyInterface;
+class InputDispatcherThread;
+
+/*
+ * The input manager is the core of the system event processing.
+ *
+ * The input manager uses two threads.
+ *
+ * 1. The InputReaderThread (called "InputReader") reads and preprocesses raw input events,
+ *    applies policy, and posts messages to a queue managed by the DispatcherThread.
+ * 2. The InputDispatcherThread (called "InputDispatcher") thread waits for new events on the
+ *    queue and asynchronously dispatches them to applications.
+ *
+ * By design, the InputReaderThread class and InputDispatcherThread class do not share any
+ * internal state.  Moreover, all communication is done one way from the InputReaderThread
+ * into the InputDispatcherThread and never the reverse.  Both classes may interact with the
+ * InputDispatchPolicy, however.
+ *
+ * The InputManager class never makes any calls into Java itself.  Instead, the
+ * InputDispatchPolicy is responsible for performing all external interactions with the
+ * system, including calling DVM services.
+ */
+class InputManagerInterface : public virtual RefBase {
+protected:
+    InputManagerInterface() { }
+    virtual ~InputManagerInterface() { }
+
+public:
+    /* Starts the input manager threads. */
+    virtual status_t start() = 0;
+
+    /* Stops the input manager threads and waits for them to exit. */
+    virtual status_t stop() = 0;
+
+    /* Registers an input channel prior to using it as the target of an event. */
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel) = 0;
+
+    /* Unregisters an input channel. */
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) = 0;
+
+    /* Injects an input event and optionally waits for sync.
+     * The synchronization mode determines whether the method blocks while waiting for
+     * input injection to proceed.
+     * Returns one of the INPUT_EVENT_INJECTION_XXX constants.
+     */
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) = 0;
+
+    /* Preempts input dispatch in progress by making pending synchronous
+     * dispatches asynchronous instead.  This method is generally called during a focus
+     * transition from one application to the next so as to enable the new application
+     * to start receiving input as soon as possible without having to wait for the
+     * old application to finish up.
+     */
+    virtual void preemptInputDispatch() = 0;
+
+    /* Gets input device configuration. */
+    virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
+
+    /* Gets information about the specified input device.
+     * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
+     * was no such device.
+     */
+    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
+
+    /* Gets the list of all registered device ids. */
+    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
+
+    /* Queries current input state. */
+    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t scanCode) = 0;
+    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t keyCode) = 0;
+    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+            int32_t sw) = 0;
+
+    /* Determines whether physical keys exist for the given framework-domain key codes. */
+    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
+};
+
+class InputManager : public InputManagerInterface {
+protected:
+    virtual ~InputManager();
+
+public:
+    InputManager(
+            const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& readerPolicy,
+            const sp<InputDispatcherPolicyInterface>& dispatcherPolicy);
+
+    // (used for testing purposes)
+    InputManager(
+            const sp<InputReaderInterface>& reader,
+            const sp<InputDispatcherInterface>& dispatcher);
+
+    virtual status_t start();
+    virtual status_t stop();
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel);
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
+
+    virtual void preemptInputDispatch();
+
+    virtual void getInputConfiguration(InputConfiguration* outConfiguration);
+    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
+    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
+    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t scanCode);
+    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t keyCode);
+    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+            int32_t sw);
+    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
+
+private:
+    sp<InputReaderInterface> mReader;
+    sp<InputReaderThread> mReaderThread;
+
+    sp<InputDispatcherInterface> mDispatcher;
+    sp<InputDispatcherThread> mDispatcherThread;
+
+    void initialize();
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_MANAGER_H
diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h
new file mode 100644
index 0000000..7a089a4
--- /dev/null
+++ b/include/ui/InputReader.h
@@ -0,0 +1,946 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef _UI_INPUT_READER_H
+#define _UI_INPUT_READER_H
+
+#include <ui/EventHub.h>
+#include <ui/Input.h>
+#include <ui/InputDispatcher.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/BitSet.h>
+
+#include <stddef.h>
+#include <unistd.h>
+
+namespace android {
+
+class InputDevice;
+class InputMapper;
+
+/* Describes a virtual key. */
+struct VirtualKeyDefinition {
+    int32_t scanCode;
+
+    // configured position data, specified in display coords
+    int32_t centerX;
+    int32_t centerY;
+    int32_t width;
+    int32_t height;
+};
+
+
+/* Specifies input device calibration settings. */
+class InputDeviceCalibration {
+public:
+    InputDeviceCalibration();
+
+    void clear();
+    void addProperty(const String8& key, const String8& value);
+
+    bool tryGetProperty(const String8& key, String8& outValue) const;
+    bool tryGetProperty(const String8& key, int32_t& outValue) const;
+    bool tryGetProperty(const String8& key, float& outValue) const;
+
+private:
+    KeyedVector<String8, String8> mProperties;
+};
+
+
+/*
+ * Input reader policy interface.
+ *
+ * The input reader policy is used by the input reader to interact with the Window Manager
+ * and other system components.
+ *
+ * The actual implementation is partially supported by callbacks into the DVM
+ * via JNI.  This interface is also mocked in the unit tests.
+ */
+class InputReaderPolicyInterface : public virtual RefBase {
+protected:
+    InputReaderPolicyInterface() { }
+    virtual ~InputReaderPolicyInterface() { }
+
+public:
+    /* Display orientations. */
+    enum {
+        ROTATION_0 = 0,
+        ROTATION_90 = 1,
+        ROTATION_180 = 2,
+        ROTATION_270 = 3
+    };
+
+    /* Actions returned by interceptXXX methods. */
+    enum {
+        // The input dispatcher should do nothing and discard the input unless other
+        // flags are set.
+        ACTION_NONE = 0,
+
+        // The input dispatcher should dispatch the input to the application.
+        ACTION_DISPATCH = 0x00000001,
+
+        // The input dispatcher should perform special filtering in preparation for
+        // a pending app switch.
+        ACTION_APP_SWITCH_COMING = 0x00000002,
+    };
+
+    /* Gets information about the display with the specified id.
+     * Returns true if the display info is available, false otherwise.
+     */
+    virtual bool getDisplayInfo(int32_t displayId,
+            int32_t* width, int32_t* height, int32_t* orientation) = 0;
+
+    /* Provides feedback for a virtual key down.
+     */
+    virtual void virtualKeyDownFeedback() = 0;
+
+    /* Intercepts a key event.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * Returns a policy action constant such as ACTION_DISPATCH.
+     */
+    virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
+            bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) = 0;
+
+    /* Intercepts a switch event.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * Switches are not dispatched to applications so this method should
+     * usually return ACTION_NONE.
+     */
+    virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+            uint32_t& policyFlags) = 0;
+
+    /* Intercepts a generic touch, trackball or other event.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * Returns a policy action constant such as ACTION_DISPATCH.
+     */
+    virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags) = 0;
+
+    /* Determines whether to turn on some hacks we have to improve the touch interaction with a
+     * certain device whose screen currently is not all that good.
+     */
+    virtual bool filterTouchEvents() = 0;
+
+    /* Determines whether to turn on some hacks to improve touch interaction with another device
+     * where touch coordinate data can get corrupted.
+     */
+    virtual bool filterJumpyTouchEvents() = 0;
+
+    /* Gets the configured virtual key definitions for an input device. */
+    virtual void getVirtualKeyDefinitions(const String8& deviceName,
+            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
+
+    /* Gets the calibration for an input device. */
+    virtual void getInputDeviceCalibration(const String8& deviceName,
+            InputDeviceCalibration& outCalibration) = 0;
+
+    /* Gets the excluded device names for the platform. */
+    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
+};
+
+
+/* Processes raw input events and sends cooked event data to an input dispatcher. */
+class InputReaderInterface : public virtual RefBase {
+protected:
+    InputReaderInterface() { }
+    virtual ~InputReaderInterface() { }
+
+public:
+    /* Runs a single iteration of the processing loop.
+     * Nominally reads and processes one incoming message from the EventHub.
+     *
+     * This method should be called on the input reader thread.
+     */
+    virtual void loopOnce() = 0;
+
+    /* Gets the current input device configuration.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void getInputConfiguration(InputConfiguration* outConfiguration) = 0;
+
+    /* Gets information about the specified input device.
+     * Returns OK if the device information was obtained or NAME_NOT_FOUND if there
+     * was no such device.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) = 0;
+
+    /* Gets the list of all registered device ids. */
+    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds) = 0;
+
+    /* Query current input state. */
+    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t scanCode) = 0;
+    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t keyCode) = 0;
+    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+            int32_t sw) = 0;
+
+    /* Determine whether physical keys exist for the given framework-domain key codes. */
+    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
+};
+
+
+/* Internal interface used by individual input devices to access global input device state
+ * and parameters maintained by the input reader.
+ */
+class InputReaderContext {
+protected:
+    InputReaderContext() { }
+    virtual ~InputReaderContext() { }
+
+public:
+    virtual void updateGlobalMetaState() = 0;
+    virtual int32_t getGlobalMetaState() = 0;
+
+    virtual InputReaderPolicyInterface* getPolicy() = 0;
+    virtual InputDispatcherInterface* getDispatcher() = 0;
+    virtual EventHubInterface* getEventHub() = 0;
+};
+
+
+/* The input reader reads raw event data from the event hub and processes it into input events
+ * that it sends to the input dispatcher.  Some functions of the input reader, such as early
+ * event filtering in low power states, are controlled by a separate policy object.
+ *
+ * IMPORTANT INVARIANT:
+ *     Because the policy and dispatcher can potentially block or cause re-entrance into
+ *     the input reader, the input reader never calls into other components while holding
+ *     an exclusive internal lock whenever re-entrance can happen.
+ */
+class InputReader : public InputReaderInterface, private InputReaderContext {
+public:
+    InputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputDispatcherInterface>& dispatcher);
+    virtual ~InputReader();
+
+    virtual void loopOnce();
+
+    virtual void getInputConfiguration(InputConfiguration* outConfiguration);
+
+    virtual status_t getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo);
+    virtual void getInputDeviceIds(Vector<int32_t>& outDeviceIds);
+
+    virtual int32_t getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t scanCode);
+    virtual int32_t getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+            int32_t keyCode);
+    virtual int32_t getSwitchState(int32_t deviceId, uint32_t sourceMask,
+            int32_t sw);
+
+    virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
+            size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
+
+private:
+    sp<EventHubInterface> mEventHub;
+    sp<InputReaderPolicyInterface> mPolicy;
+    sp<InputDispatcherInterface> mDispatcher;
+
+    virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
+    virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
+    virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
+
+    // This reader/writer lock guards the list of input devices.
+    // The writer lock must be held whenever the list of input devices is modified
+    //   and then promptly released.
+    // The reader lock must be held whenever the list of input devices is traversed or an
+    //   input device in the list is accessed.
+    // This lock only protects the registry and prevents inadvertent deletion of device objects
+    // that are in use.  Individual devices are responsible for guarding their own internal state
+    // as needed for concurrent operation.
+    RWLock mDeviceRegistryLock;
+    KeyedVector<int32_t, InputDevice*> mDevices;
+
+    // low-level input event decoding and device management
+    void process(const RawEvent* rawEvent);
+
+    void addDevice(nsecs_t when, int32_t deviceId);
+    void removeDevice(nsecs_t when, int32_t deviceId);
+    InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
+    void configureExcludedDevices();
+
+    void consumeEvent(const RawEvent* rawEvent);
+
+    void handleConfigurationChanged(nsecs_t when);
+
+    // state management for all devices
+    Mutex mStateLock;
+
+    int32_t mGlobalMetaState;
+    virtual void updateGlobalMetaState();
+    virtual int32_t getGlobalMetaState();
+
+    InputConfiguration mInputConfiguration;
+    void updateInputConfiguration();
+
+    // state queries
+    typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+    int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+            GetStateFunc getStateFunc);
+    bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+};
+
+
+/* Reads raw events from the event hub and processes them, endlessly. */
+class InputReaderThread : public Thread {
+public:
+    InputReaderThread(const sp<InputReaderInterface>& reader);
+    virtual ~InputReaderThread();
+
+private:
+    sp<InputReaderInterface> mReader;
+
+    virtual bool threadLoop();
+};
+
+
+/* Represents the state of a single input device. */
+class InputDevice {
+public:
+    InputDevice(InputReaderContext* context, int32_t id, const String8& name);
+    ~InputDevice();
+
+    inline InputReaderContext* getContext() { return mContext; }
+    inline int32_t getId() { return mId; }
+    inline const String8& getName() { return mName; }
+    inline uint32_t getSources() { return mSources; }
+
+    inline bool isIgnored() { return mMappers.isEmpty(); }
+
+    void addMapper(InputMapper* mapper);
+    void configure();
+    void reset();
+    void process(const RawEvent* rawEvent);
+
+    void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
+    int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+    bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    int32_t getMetaState();
+
+    inline const InputDeviceCalibration& getCalibration() {
+        return mCalibration;
+    }
+
+private:
+    InputReaderContext* mContext;
+    int32_t mId;
+
+    Vector<InputMapper*> mMappers;
+
+    String8 mName;
+    uint32_t mSources;
+
+    typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+    int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
+
+    InputDeviceCalibration mCalibration;
+};
+
+
+/* An input mapper transforms raw input events into cooked event data.
+ * A single input device can have multiple associated input mappers in order to interpret
+ * different classes of events.
+ */
+class InputMapper {
+public:
+    InputMapper(InputDevice* device);
+    virtual ~InputMapper();
+
+    inline InputDevice* getDevice() { return mDevice; }
+    inline int32_t getDeviceId() { return mDevice->getId(); }
+    inline const String8 getDeviceName() { return mDevice->getName(); }
+    inline InputReaderContext* getContext() { return mContext; }
+    inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
+    inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
+    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+
+    virtual uint32_t getSources() = 0;
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void configure();
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent) = 0;
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    virtual int32_t getMetaState();
+
+protected:
+    InputDevice* mDevice;
+    InputReaderContext* mContext;
+
+    bool applyStandardPolicyActions(nsecs_t when, int32_t policyActions);
+};
+
+
+class SwitchInputMapper : public InputMapper {
+public:
+    SwitchInputMapper(InputDevice* device);
+    virtual ~SwitchInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+
+private:
+    void processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue);
+};
+
+
+class KeyboardInputMapper : public InputMapper {
+public:
+    KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, uint32_t sources,
+            int32_t keyboardType);
+    virtual ~KeyboardInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    virtual int32_t getMetaState();
+
+private:
+    Mutex mLock;
+
+    struct KeyDown {
+        int32_t keyCode;
+        int32_t scanCode;
+    };
+
+    int32_t mAssociatedDisplayId;
+    uint32_t mSources;
+    int32_t mKeyboardType;
+
+    struct LockedState {
+        Vector<KeyDown> keyDowns; // keys that are down
+        int32_t metaState;
+        nsecs_t downTime; // time of most recent key down
+    } mLocked;
+
+    void initializeLocked();
+
+    bool isKeyboardOrGamepadKey(int32_t scanCode);
+
+    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
+            uint32_t policyFlags);
+    void applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags,
+            bool down, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime);
+
+    ssize_t findKeyDownLocked(int32_t scanCode);
+};
+
+
+class TrackballInputMapper : public InputMapper {
+public:
+    TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~TrackballInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+
+private:
+    // Amount that trackball needs to move in order to generate a key event.
+    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
+
+    Mutex mLock;
+
+    int32_t mAssociatedDisplayId;
+
+    struct Accumulator {
+        enum {
+            FIELD_BTN_MOUSE = 1,
+            FIELD_REL_X = 2,
+            FIELD_REL_Y = 4
+        };
+
+        uint32_t fields;
+
+        bool btnMouse;
+        int32_t relX;
+        int32_t relY;
+
+        inline void clear() {
+            fields = 0;
+        }
+    } mAccumulator;
+
+    float mXScale;
+    float mYScale;
+    float mXPrecision;
+    float mYPrecision;
+
+    struct LockedState {
+        bool down;
+        nsecs_t downTime;
+    } mLocked;
+
+    void initializeLocked();
+
+    void sync(nsecs_t when);
+    void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+            PointerCoords* pointerCoords, nsecs_t downTime);
+};
+
+
+class TouchInputMapper : public InputMapper {
+public:
+    TouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~TouchInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void configure();
+    virtual void reset();
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+protected:
+    /* Maximum pointer id value supported.
+     * (This is limited by our use of BitSet32 to track pointer assignments.) */
+    static const uint32_t MAX_POINTER_ID = 31;
+
+    Mutex mLock;
+
+    struct VirtualKey {
+        int32_t keyCode;
+        int32_t scanCode;
+        uint32_t flags;
+
+        // computed hit box, specified in touch screen coords based on known display size
+        int32_t hitLeft;
+        int32_t hitTop;
+        int32_t hitRight;
+        int32_t hitBottom;
+
+        inline bool isHit(int32_t x, int32_t y) const {
+            return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
+        }
+    };
+
+    // Raw data for a single pointer.
+    struct PointerData {
+        uint32_t id;
+        int32_t x;
+        int32_t y;
+        int32_t pressure;
+        int32_t touchMajor;
+        int32_t touchMinor;
+        int32_t toolMajor;
+        int32_t toolMinor;
+        int32_t orientation;
+    };
+
+    // Raw data for a collection of pointers including a pointer id mapping table.
+    struct TouchData {
+        uint32_t pointerCount;
+        PointerData pointers[MAX_POINTERS];
+        BitSet32 idBits;
+        uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+        void copyFrom(const TouchData& other) {
+            pointerCount = other.pointerCount;
+            idBits = other.idBits;
+
+            for (uint32_t i = 0; i < pointerCount; i++) {
+                pointers[i] = other.pointers[i];
+
+                int id = pointers[i].id;
+                idToIndex[id] = other.idToIndex[id];
+            }
+        }
+
+        inline void clear() {
+            pointerCount = 0;
+            idBits.clear();
+        }
+    };
+
+    int32_t mAssociatedDisplayId;
+
+    // Immutable configuration parameters.
+    struct Parameters {
+        bool useBadTouchFilter;
+        bool useJumpyTouchFilter;
+        bool useAveragingTouchFilter;
+    } mParameters;
+
+    // Immutable calibration parameters in parsed form.
+    struct Calibration {
+        // Touch Area
+        enum TouchAreaCalibration {
+            TOUCH_AREA_CALIBRATION_DEFAULT,
+            TOUCH_AREA_CALIBRATION_NONE,
+            TOUCH_AREA_CALIBRATION_GEOMETRIC,
+            TOUCH_AREA_CALIBRATION_PRESSURE,
+        };
+
+        TouchAreaCalibration touchAreaCalibration;
+
+        // Tool Area
+        enum ToolAreaCalibration {
+            TOOL_AREA_CALIBRATION_DEFAULT,
+            TOOL_AREA_CALIBRATION_NONE,
+            TOOL_AREA_CALIBRATION_GEOMETRIC,
+            TOOL_AREA_CALIBRATION_LINEAR,
+        };
+
+        ToolAreaCalibration toolAreaCalibration;
+        bool haveToolAreaLinearScale;
+        float toolAreaLinearScale;
+        bool haveToolAreaLinearBias;
+        float toolAreaLinearBias;
+        bool haveToolAreaIsSummed;
+        int32_t toolAreaIsSummed;
+
+        // Pressure
+        enum PressureCalibration {
+            PRESSURE_CALIBRATION_DEFAULT,
+            PRESSURE_CALIBRATION_NONE,
+            PRESSURE_CALIBRATION_PHYSICAL,
+            PRESSURE_CALIBRATION_AMPLITUDE,
+        };
+        enum PressureSource {
+            PRESSURE_SOURCE_DEFAULT,
+            PRESSURE_SOURCE_PRESSURE,
+            PRESSURE_SOURCE_TOUCH,
+        };
+
+        PressureCalibration pressureCalibration;
+        PressureSource pressureSource;
+        bool havePressureScale;
+        float pressureScale;
+
+        // Size
+        enum SizeCalibration {
+            SIZE_CALIBRATION_DEFAULT,
+            SIZE_CALIBRATION_NONE,
+            SIZE_CALIBRATION_NORMALIZED,
+        };
+
+        SizeCalibration sizeCalibration;
+
+        // Orientation
+        enum OrientationCalibration {
+            ORIENTATION_CALIBRATION_DEFAULT,
+            ORIENTATION_CALIBRATION_NONE,
+            ORIENTATION_CALIBRATION_INTERPOLATED,
+        };
+
+        OrientationCalibration orientationCalibration;
+    } mCalibration;
+
+    // Raw axis information from the driver.
+    struct RawAxes {
+        RawAbsoluteAxisInfo x;
+        RawAbsoluteAxisInfo y;
+        RawAbsoluteAxisInfo pressure;
+        RawAbsoluteAxisInfo touchMajor;
+        RawAbsoluteAxisInfo touchMinor;
+        RawAbsoluteAxisInfo toolMajor;
+        RawAbsoluteAxisInfo toolMinor;
+        RawAbsoluteAxisInfo orientation;
+    } mRawAxes;
+
+    // Current and previous touch sample data.
+    TouchData mCurrentTouch;
+    TouchData mLastTouch;
+
+    // The time the primary pointer last went down.
+    nsecs_t mDownTime;
+
+    struct LockedState {
+        Vector<VirtualKey> virtualKeys;
+
+        // The surface orientation and width and height set by configureSurfaceLocked().
+        int32_t surfaceOrientation;
+        int32_t surfaceWidth, surfaceHeight;
+
+        // Translation and scaling factors, orientation-independent.
+        int32_t xOrigin;
+        float xScale;
+        float xPrecision;
+
+        int32_t yOrigin;
+        float yScale;
+        float yPrecision;
+
+        float geometricScale;
+
+        float toolAreaLinearScale;
+        float toolAreaLinearBias;
+
+        float pressureScale;
+
+        float sizeScale;
+
+        float orientationScale;
+
+        // Oriented motion ranges for input device info.
+        struct OrientedRanges {
+            InputDeviceInfo::MotionRange x;
+            InputDeviceInfo::MotionRange y;
+
+            bool havePressure;
+            InputDeviceInfo::MotionRange pressure;
+
+            bool haveSize;
+            InputDeviceInfo::MotionRange size;
+
+            bool haveTouchArea;
+            InputDeviceInfo::MotionRange touchMajor;
+            InputDeviceInfo::MotionRange touchMinor;
+
+            bool haveToolArea;
+            InputDeviceInfo::MotionRange toolMajor;
+            InputDeviceInfo::MotionRange toolMinor;
+
+            bool haveOrientation;
+            InputDeviceInfo::MotionRange orientation;
+        } orientedRanges;
+
+        // Oriented dimensions and precision.
+        float orientedSurfaceWidth, orientedSurfaceHeight;
+        float orientedXPrecision, orientedYPrecision;
+
+        struct CurrentVirtualKeyState {
+            bool down;
+            nsecs_t downTime;
+            int32_t keyCode;
+            int32_t scanCode;
+        } currentVirtualKey;
+    } mLocked;
+
+    virtual void configureParameters();
+    virtual void configureRawAxes();
+    virtual void logRawAxes();
+    virtual bool configureSurfaceLocked();
+    virtual void configureVirtualKeysLocked();
+    virtual void parseCalibration();
+    virtual void resolveCalibration();
+    virtual void logCalibration();
+
+    enum TouchResult {
+        // Dispatch the touch normally.
+        DISPATCH_TOUCH,
+        // Do not dispatch the touch, but keep tracking the current stroke.
+        SKIP_TOUCH,
+        // Do not dispatch the touch, and drop all information associated with the current stoke
+        // so the next movement will appear as a new down.
+        DROP_STROKE
+    };
+
+    void syncTouch(nsecs_t when, bool havePointerIds);
+
+private:
+    /* Maximum number of historical samples to average. */
+    static const uint32_t AVERAGING_HISTORY_SIZE = 5;
+
+    /* Slop distance for jumpy pointer detection.
+     * The vertical range of the screen divided by this is our epsilon value. */
+    static const uint32_t JUMPY_EPSILON_DIVISOR = 212;
+
+    /* Number of jumpy points to drop for touchscreens that need it. */
+    static const uint32_t JUMPY_TRANSITION_DROPS = 3;
+    static const uint32_t JUMPY_DROP_LIMIT = 3;
+
+    /* Maximum squared distance for averaging.
+     * If moving farther than this, turn of averaging to avoid lag in response. */
+    static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75;
+
+    struct AveragingTouchFilterState {
+        // Individual history tracks are stored by pointer id
+        uint32_t historyStart[MAX_POINTERS];
+        uint32_t historyEnd[MAX_POINTERS];
+        struct {
+            struct {
+                int32_t x;
+                int32_t y;
+                int32_t pressure;
+            } pointers[MAX_POINTERS];
+        } historyData[AVERAGING_HISTORY_SIZE];
+    } mAveragingTouchFilter;
+
+    struct JumpyTouchFilterState {
+        uint32_t jumpyPointsDropped;
+    } mJumpyTouchFilter;
+
+    struct PointerDistanceHeapElement {
+        uint32_t currentPointerIndex : 8;
+        uint32_t lastPointerIndex : 8;
+        uint64_t distance : 48; // squared distance
+    };
+
+    void initializeLocked();
+
+    TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
+    void dispatchTouches(nsecs_t when, uint32_t policyFlags);
+    void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
+            BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
+            int32_t motionEventAction);
+
+    void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+            int32_t keyEventAction, int32_t keyEventFlags,
+            int32_t keyCode, int32_t scanCode, nsecs_t downTime);
+
+    bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
+    const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
+
+    bool applyBadTouchFilter();
+    bool applyJumpyTouchFilter();
+    void applyAveragingTouchFilter();
+    void calculatePointerIds();
+};
+
+
+class SingleTouchInputMapper : public TouchInputMapper {
+public:
+    SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~SingleTouchInputMapper();
+
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+protected:
+    virtual void configureRawAxes();
+
+private:
+    struct Accumulator {
+        enum {
+            FIELD_BTN_TOUCH = 1,
+            FIELD_ABS_X = 2,
+            FIELD_ABS_Y = 4,
+            FIELD_ABS_PRESSURE = 8,
+            FIELD_ABS_TOOL_WIDTH = 16
+        };
+
+        uint32_t fields;
+
+        bool btnTouch;
+        int32_t absX;
+        int32_t absY;
+        int32_t absPressure;
+        int32_t absToolWidth;
+
+        inline void clear() {
+            fields = 0;
+        }
+    } mAccumulator;
+
+    bool mDown;
+    int32_t mX;
+    int32_t mY;
+    int32_t mPressure;
+    int32_t mToolWidth;
+
+    void initialize();
+
+    void sync(nsecs_t when);
+};
+
+
+class MultiTouchInputMapper : public TouchInputMapper {
+public:
+    MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~MultiTouchInputMapper();
+
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+protected:
+    virtual void configureRawAxes();
+
+private:
+    struct Accumulator {
+        enum {
+            FIELD_ABS_MT_POSITION_X = 1,
+            FIELD_ABS_MT_POSITION_Y = 2,
+            FIELD_ABS_MT_TOUCH_MAJOR = 4,
+            FIELD_ABS_MT_TOUCH_MINOR = 8,
+            FIELD_ABS_MT_WIDTH_MAJOR = 16,
+            FIELD_ABS_MT_WIDTH_MINOR = 32,
+            FIELD_ABS_MT_ORIENTATION = 64,
+            FIELD_ABS_MT_TRACKING_ID = 128,
+            FIELD_ABS_MT_PRESSURE = 256,
+        };
+
+        uint32_t pointerCount;
+        struct Pointer {
+            uint32_t fields;
+
+            int32_t absMTPositionX;
+            int32_t absMTPositionY;
+            int32_t absMTTouchMajor;
+            int32_t absMTTouchMinor;
+            int32_t absMTWidthMajor;
+            int32_t absMTWidthMinor;
+            int32_t absMTOrientation;
+            int32_t absMTTrackingId;
+            int32_t absMTPressure;
+
+            inline void clear() {
+                fields = 0;
+            }
+        } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
+
+        inline void clear() {
+            pointerCount = 0;
+            pointers[0].clear();
+        }
+    } mAccumulator;
+
+    void initialize();
+
+    void sync(nsecs_t when);
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_READER_H
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
new file mode 100644
index 0000000..82831e2
--- /dev/null
+++ b/include/ui/InputTransport.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef _UI_INPUT_TRANSPORT_H
+#define _UI_INPUT_TRANSPORT_H
+
+/**
+ * Native input transport.
+ *
+ * Uses anonymous shared memory as a whiteboard for sending input events from an
+ * InputPublisher to an InputConsumer and ensuring appropriate synchronization.
+ * One interesting feature is that published events can be updated in place as long as they
+ * have not yet been consumed.
+ *
+ * The InputPublisher and InputConsumer only take care of transferring event data
+ * over an InputChannel and sending synchronization signals.  The InputDispatcher and InputQueue
+ * build on these abstractions to add multiplexing and queueing.
+ */
+
+#include <semaphore.h>
+#include <ui/Input.h>
+#include <utils/Errors.h>
+#include <utils/PollLoop.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+/*
+ * An input channel consists of a shared memory buffer and a pair of pipes
+ * used to send input messages from an InputPublisher to an InputConsumer
+ * across processes.  Each channel has a descriptive name for debugging purposes.
+ *
+ * Each endpoint has its own InputChannel object that specifies its own file descriptors.
+ *
+ * The input channel is closed when all references to it are released.
+ */
+class InputChannel : public RefBase {
+protected:
+    virtual ~InputChannel();
+
+public:
+    InputChannel(const String8& name, int32_t ashmemFd, int32_t receivePipeFd,
+            int32_t sendPipeFd);
+
+    /* Creates a pair of input channels and their underlying shared memory buffers
+     * and pipes.
+     *
+     * Returns OK on success.
+     */
+    static status_t openInputChannelPair(const String8& name,
+            sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel);
+
+    inline String8 getName() const { return mName; }
+    inline int32_t getAshmemFd() const { return mAshmemFd; }
+    inline int32_t getReceivePipeFd() const { return mReceivePipeFd; }
+    inline int32_t getSendPipeFd() const { return mSendPipeFd; }
+
+    /* Sends a signal to the other endpoint.
+     *
+     * Returns OK on success.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t sendSignal(char signal);
+
+    /* Receives a signal send by the other endpoint.
+     * (Should only call this after poll() indicates that the receivePipeFd has available input.)
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Returns DEAD_OBJECT if the channel's peer has been closed.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveSignal(char* outSignal);
+
+private:
+    String8 mName;
+    int32_t mAshmemFd;
+    int32_t mReceivePipeFd;
+    int32_t mSendPipeFd;
+};
+
+/*
+ * Private intermediate representation of input events as messages written into an
+ * ashmem buffer.
+ */
+struct InputMessage {
+    /* Semaphore count is set to 1 when the message is published.
+     * It becomes 0 transiently while the publisher updates the message.
+     * It becomes 0 permanently when the consumer consumes the message.
+     */
+    sem_t semaphore;
+
+    /* Initialized to false by the publisher.
+     * Set to true by the consumer when it consumes the message.
+     */
+    bool consumed;
+
+    int32_t type;
+
+    struct SampleData {
+        nsecs_t eventTime;
+        PointerCoords coords[0]; // variable length
+    };
+
+    int32_t deviceId;
+    int32_t source;
+
+    union {
+        struct {
+            int32_t action;
+            int32_t flags;
+            int32_t keyCode;
+            int32_t scanCode;
+            int32_t metaState;
+            int32_t repeatCount;
+            nsecs_t downTime;
+            nsecs_t eventTime;
+        } key;
+
+        struct {
+            int32_t action;
+            int32_t flags;
+            int32_t metaState;
+            int32_t edgeFlags;
+            nsecs_t downTime;
+            float xOffset;
+            float yOffset;
+            float xPrecision;
+            float yPrecision;
+            size_t pointerCount;
+            int32_t pointerIds[MAX_POINTERS];
+            size_t sampleCount;
+            SampleData sampleData[0]; // variable length
+        } motion;
+    };
+
+    /* Gets the number of bytes to add to step to the next SampleData object in a motion
+     * event message for a given number of pointers.
+     */
+    static inline size_t sampleDataStride(size_t pointerCount) {
+        return sizeof(InputMessage::SampleData) + pointerCount * sizeof(PointerCoords);
+    }
+
+    /* Adds the SampleData stride to the given pointer. */
+    static inline SampleData* sampleDataPtrIncrement(SampleData* ptr, size_t stride) {
+        return reinterpret_cast<InputMessage::SampleData*>(reinterpret_cast<char*>(ptr) + stride);
+    }
+};
+
+/*
+ * Publishes input events to an anonymous shared memory buffer.
+ * Uses atomic operations to coordinate shared access with a single concurrent consumer.
+ */
+class InputPublisher {
+public:
+    /* Creates a publisher associated with an input channel. */
+    explicit InputPublisher(const sp<InputChannel>& channel);
+
+    /* Destroys the publisher and releases its input channel. */
+    ~InputPublisher();
+
+    /* Gets the underlying input channel. */
+    inline sp<InputChannel> getChannel() { return mChannel; }
+
+    /* Prepares the publisher for use.  Must be called before it is used.
+     * Returns OK on success.
+     *
+     * This method implicitly calls reset(). */
+    status_t initialize();
+
+    /* Resets the publisher to its initial state and unpins its ashmem buffer.
+     * Returns OK on success.
+     *
+     * Should be called after an event has been consumed to release resources used by the
+     * publisher until the next event is ready to be published.
+     */
+    status_t reset();
+
+    /* Publishes a key event to the ashmem buffer.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if the publisher has not been reset.
+     */
+    status_t publishKeyEvent(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t keyCode,
+            int32_t scanCode,
+            int32_t metaState,
+            int32_t repeatCount,
+            nsecs_t downTime,
+            nsecs_t eventTime);
+
+    /* Publishes a motion event to the ashmem buffer.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if the publisher has not been reset.
+     * Returns BAD_VALUE if pointerCount is less than 1 or greater than MAX_POINTERS.
+     */
+    status_t publishMotionEvent(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t edgeFlags,
+            int32_t metaState,
+            float xOffset,
+            float yOffset,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const int32_t* pointerIds,
+            const PointerCoords* pointerCoords);
+
+    /* Appends a motion sample to a motion event unless already consumed.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if the current event is not a AMOTION_EVENT_ACTION_MOVE event.
+     * Returns FAILED_TRANSACTION if the current event has already been consumed.
+     * Returns NO_MEMORY if the buffer is full and no additional samples can be added.
+     */
+    status_t appendMotionSample(
+            nsecs_t eventTime,
+            const PointerCoords* pointerCoords);
+
+    /* Sends a dispatch signal to the consumer to inform it that a new message is available.
+     *
+     * Returns OK on success.
+     * Errors probably indicate that the channel is broken.
+     */
+    status_t sendDispatchSignal();
+
+    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveFinishedSignal();
+
+private:
+    sp<InputChannel> mChannel;
+
+    size_t mAshmemSize;
+    InputMessage* mSharedMessage;
+    bool mPinned;
+    bool mSemaphoreInitialized;
+    bool mWasDispatched;
+
+    size_t mMotionEventPointerCount;
+    InputMessage::SampleData* mMotionEventSampleDataTail;
+    size_t mMotionEventSampleDataStride;
+
+    status_t publishInputEvent(
+            int32_t type,
+            int32_t deviceId,
+            int32_t source);
+};
+
+/*
+ * Consumes input events from an anonymous shared memory buffer.
+ * Uses atomic operations to coordinate shared access with a single concurrent publisher.
+ */
+class InputConsumer {
+public:
+    /* Creates a consumer associated with an input channel. */
+    explicit InputConsumer(const sp<InputChannel>& channel);
+
+    /* Destroys the consumer and releases its input channel. */
+    ~InputConsumer();
+
+    /* Gets the underlying input channel. */
+    inline sp<InputChannel> getChannel() { return mChannel; }
+
+    /* Prepares the consumer for use.  Must be called before it is used. */
+    status_t initialize();
+
+    /* Consumes the input event in the buffer and copies its contents into
+     * an InputEvent object created using the specified factory.
+     * This operation will block if the publisher is updating the event.
+     *
+     * Returns OK on success.
+     * Returns INVALID_OPERATION if there is no currently published event.
+     * Returns NO_MEMORY if the event could not be created.
+     */
+    status_t consume(InputEventFactoryInterface* factory, InputEvent** outEvent);
+
+    /* Sends a finished signal to the publisher to inform it that the current message is
+     * finished processing.
+     *
+     * Returns OK on success.
+     * Errors probably indicate that the channel is broken.
+     */
+    status_t sendFinishedSignal();
+
+    /* Receives the dispatched signal from the publisher.
+     *
+     * Returns OK on success.
+     * Returns WOULD_BLOCK if there is no signal present.
+     * Other errors probably indicate that the channel is broken.
+     */
+    status_t receiveDispatchSignal();
+
+private:
+    sp<InputChannel> mChannel;
+
+    size_t mAshmemSize;
+    InputMessage* mSharedMessage;
+
+    void populateKeyEvent(KeyEvent* keyEvent) const;
+    void populateMotionEvent(MotionEvent* motionEvent) const;
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_TRANSPORT_H
diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h
index e81d0f9..c8d6ffc 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/ui/KeycodeLabels.h
@@ -17,6 +17,8 @@
 #ifndef _UI_KEYCODE_LABELS_H
 #define _UI_KEYCODE_LABELS_H
 
+#include <android/keycodes.h>
+
 struct KeycodeLabel {
     const char *literal;
     int value;
@@ -118,117 +120,28 @@
     { "PAGE_DOWN", 93 },
     { "PICTSYMBOLS", 94 },
     { "SWITCH_CHARSET", 95 },
+    { "BUTTON_A", 96 },
+    { "BUTTON_B", 97 },
+    { "BUTTON_C", 98 },
+    { "BUTTON_X", 99 },
+    { "BUTTON_Y", 100 },
+    { "BUTTON_Z", 101 },
+    { "BUTTON_L1", 102 },
+    { "BUTTON_R1", 103 },
+    { "BUTTON_L2", 104 },
+    { "BUTTON_R2", 105 },
+    { "BUTTON_THUMBL", 106 },
+    { "BUTTON_THUMBR", 107 },
+    { "BUTTON_START", 108 },
+    { "BUTTON_SELECT", 109 },
+    { "BUTTON_MODE", 110 },
 
-    // NOTE: If you add a new keycode here you must also add it to:
-    //   (enum KeyCode, in this file)
-    //   frameworks/base/core/java/android/view/KeyEvent.java
-    //   tools/puppet_master/PuppetMaster.nav_keys.py
-    //   frameworks/base/core/res/res/values/attrs.xml
+    // NOTE: If you add a new keycode here you must also add it to several other files.
+    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
 
     { NULL, 0 }
 };
 
-// These constants need to match the above mappings.
-typedef enum KeyCode {
-    kKeyCodeUnknown = 0,
-
-    kKeyCodeSoftLeft = 1,
-    kKeyCodeSoftRight = 2,
-    kKeyCodeHome = 3,
-    kKeyCodeBack = 4,
-    kKeyCodeCall = 5,
-    kKeyCodeEndCall = 6,
-    kKeyCode0 = 7,
-    kKeyCode1 = 8,
-    kKeyCode2 = 9,
-    kKeyCode3 = 10,
-    kKeyCode4 = 11,
-    kKeyCode5 = 12,
-    kKeyCode6 = 13,
-    kKeyCode7 = 14,
-    kKeyCode8 = 15,
-    kKeyCode9 = 16,
-    kKeyCodeStar = 17,
-    kKeyCodePound = 18,
-    kKeyCodeDpadUp = 19,
-    kKeyCodeDpadDown = 20,
-    kKeyCodeDpadLeft = 21,
-    kKeyCodeDpadRight = 22,
-    kKeyCodeDpadCenter = 23,
-    kKeyCodeVolumeUp = 24,
-    kKeyCodeVolumeDown = 25,
-    kKeyCodePower = 26,
-    kKeyCodeCamera = 27,
-    kKeyCodeClear = 28,
-    kKeyCodeA = 29,
-    kKeyCodeB = 30,
-    kKeyCodeC = 31,
-    kKeyCodeD = 32,
-    kKeyCodeE = 33,
-    kKeyCodeF = 34,
-    kKeyCodeG = 35,
-    kKeyCodeH = 36,
-    kKeyCodeI = 37,
-    kKeyCodeJ = 38,
-    kKeyCodeK = 39,
-    kKeyCodeL = 40,
-    kKeyCodeM = 41,
-    kKeyCodeN = 42,
-    kKeyCodeO = 43,
-    kKeyCodeP = 44,
-    kKeyCodeQ = 45,
-    kKeyCodeR = 46,
-    kKeyCodeS = 47,
-    kKeyCodeT = 48,
-    kKeyCodeU = 49,
-    kKeyCodeV = 50,
-    kKeyCodeW = 51,
-    kKeyCodeX = 52,
-    kKeyCodeY = 53,
-    kKeyCodeZ = 54,
-    kKeyCodeComma = 55,
-    kKeyCodePeriod = 56,
-    kKeyCodeAltLeft = 57,
-    kKeyCodeAltRight = 58,
-    kKeyCodeShiftLeft = 59,
-    kKeyCodeShiftRight = 60,
-    kKeyCodeTab = 61,
-    kKeyCodeSpace = 62,
-    kKeyCodeSym = 63,
-    kKeyCodeExplorer = 64,
-    kKeyCodeEnvelope = 65,
-    kKeyCodeNewline = 66,
-    kKeyCodeDel = 67,
-    kKeyCodeGrave = 68,
-    kKeyCodeMinus = 69,
-    kKeyCodeEquals = 70,
-    kKeyCodeLeftBracket = 71,
-    kKeyCodeRightBracket = 72,
-    kKeyCodeBackslash = 73,
-    kKeyCodeSemicolon = 74,
-    kKeyCodeApostrophe = 75,
-    kKeyCodeSlash = 76,
-    kKeyCodeAt = 77,
-    kKeyCodeNum = 78,
-    kKeyCodeHeadSetHook = 79,
-    kKeyCodeFocus = 80,
-    kKeyCodePlus = 81,
-    kKeyCodeMenu = 82,
-    kKeyCodeNotification = 83,
-    kKeyCodeSearch = 84,
-    kKeyCodePlayPause = 85,
-    kKeyCodeStop = 86,
-    kKeyCodeNextSong = 87,
-    kKeyCodePreviousSong = 88,
-    kKeyCodeRewind = 89,
-    kKeyCodeForward = 90,
-    kKeyCodeMute = 91,
-    kKeyCodePageUp = 92,
-    kKeyCodePageDown = 93,
-    kKeyCodePictSymbols = 94,
-    kKeyCodeSwitchCharset = 95
-} KeyCode;
-
 static const KeycodeLabel FLAGS[] = {
     { "WAKE", 0x00000001 },
     { "WAKE_DROPPED", 0x00000002 },
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index a213c09..4e65a2d 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -20,31 +20,28 @@
 #include <utils/TypeHelpers.h>
 #include <ui/Point.h>
 
+#include <android/rect.h>
+
 namespace android {
 
-class Rect
+class Rect : public ARect
 {
 public:
-    int left;
-    int top;
-    int right;
-    int bottom;
-
-    typedef int value_type;
+    typedef int32_t value_type;
 
     // we don't provide copy-ctor and operator= on purpose
     // because we want the compiler generated versions
 
     inline Rect() {
     }
-    inline Rect(int w, int h)
-        : left(0), top(0), right(w), bottom(h) {
+    inline Rect(int32_t w, int32_t h) {
+        left = top = 0; right = w; bottom = h;
     }
-    inline Rect(int l, int t, int r, int b)
-        : left(l), top(t), right(r), bottom(b) {
+    inline Rect(int32_t l, int32_t t, int32_t r, int32_t b) {
+        left = l; top = t; right = r; bottom = b;
     }
-    inline Rect(const Point& lt, const Point& rb) 
-        : left(lt.x), top(lt.y), right(rb.x), bottom(rb.y) {
+    inline Rect(const Point& lt, const Point& rb) {
+        left = lt.x; top = lt.y; right = rb.x; bottom = rb.y;
     }
 
     void makeInvalid();
@@ -68,12 +65,12 @@
     }
 
     // rectangle's width
-    inline int width() const {
+    inline int32_t width() const {
         return right-left;
     }
     
     // rectangle's height
-    inline int height() const {
+    inline int32_t height() const {
         return bottom-top;
     }
 
@@ -136,12 +133,12 @@
     const Rect operator + (const Point& rhs) const;
     const Rect operator - (const Point& rhs) const;
 
-    void translate(int dx, int dy) { // legacy, don't use.
+    void translate(int32_t dx, int32_t dy) { // legacy, don't use.
         offsetBy(dx, dy);
     }
  
-    Rect&   offsetTo(int x, int y);
-    Rect&   offsetBy(int x, int y);
+    Rect&   offsetTo(int32_t x, int32_t y);
+    Rect&   offsetBy(int32_t x, int32_t y);
     bool    intersect(const Rect& with, Rect* result) const;
 };
 
diff --git a/include/ui/android_native_buffer.h b/include/ui/android_native_buffer.h
index 9c92af8..402843e 100644
--- a/include/ui/android_native_buffer.h
+++ b/include/ui/android_native_buffer.h
@@ -33,6 +33,15 @@
         common.version = sizeof(android_native_buffer_t);
         memset(common.reserved, 0, sizeof(common.reserved));
     }
+
+    // Implement the methods that sp<android_native_buffer_t> expects so that it
+    // can be used to automatically refcount android_native_buffer_t's.
+    void incStrong(const void* id) const {
+        common.incRef(const_cast<android_native_base_t*>(&common));
+    }
+    void decStrong(const void* id) const {
+        common.decRef(const_cast<android_native_base_t*>(&common));
+    }
 #endif
 
     struct android_native_base_t common;
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 773fd93..d59d72b 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -22,6 +22,8 @@
 
 #include <hardware/gralloc.h>
 
+#include <android/native_window.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -41,6 +43,14 @@
 
 struct android_native_buffer_t;
 
+typedef struct android_native_rect_t
+{
+    int32_t left;
+    int32_t top;
+    int32_t right;
+    int32_t bottom;
+} android_native_rect_t;
+
 // ---------------------------------------------------------------------------
 
 typedef struct android_native_base_t
@@ -63,15 +73,19 @@
 /* attributes queriable with query() */
 enum {
     NATIVE_WINDOW_WIDTH     = 0,
-    NATIVE_WINDOW_HEIGHT    = 1,
-    NATIVE_WINDOW_FORMAT    = 2,
+    NATIVE_WINDOW_HEIGHT,
+    NATIVE_WINDOW_FORMAT,
 };
 
 /* valid operations for the (*perform)() hook */
 enum {
     NATIVE_WINDOW_SET_USAGE  = 0,
-    NATIVE_WINDOW_CONNECT    = 1,
-    NATIVE_WINDOW_DISCONNECT = 2
+    NATIVE_WINDOW_CONNECT,
+    NATIVE_WINDOW_DISCONNECT,
+    NATIVE_WINDOW_SET_CROP,
+    NATIVE_WINDOW_SET_BUFFER_COUNT,
+    NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+    NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
 };
 
 /* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -79,16 +93,39 @@
     NATIVE_WINDOW_API_EGL = 1
 };
 
-typedef struct android_native_window_t 
+/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */
+enum {
+    /* flip source image horizontally */
+    NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H ,
+    /* flip source image vertically */
+    NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
+    /* rotate source image 90 degrees clock-wise */
+    NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
+    /* rotate source image 180 degrees */
+    NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
+    /* rotate source image 270 degrees clock-wise */
+    NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
+};
+
+struct ANativeWindow 
 {
 #ifdef __cplusplus
-    android_native_window_t()
+    ANativeWindow()
         : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
     {
         common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
-        common.version = sizeof(android_native_window_t);
+        common.version = sizeof(ANativeWindow);
         memset(common.reserved, 0, sizeof(common.reserved));
     }
+
+    // Implement the methods that sp<ANativeWindow> expects so that it
+    // can be used to automatically refcount ANativeWindow's.
+    void incStrong(const void* id) const {
+        common.incRef(const_cast<android_native_base_t*>(&common));
+    }
+    void decStrong(const void* id) const {
+        common.decRef(const_cast<android_native_base_t*>(&common));
+    }
 #endif
     
     struct android_native_base_t common;
@@ -115,7 +152,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*setSwapInterval)(struct android_native_window_t* window,
+    int     (*setSwapInterval)(struct ANativeWindow* window,
                 int interval);
     
     /*
@@ -125,7 +162,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*dequeueBuffer)(struct android_native_window_t* window, 
+    int     (*dequeueBuffer)(struct ANativeWindow* window,
                 struct android_native_buffer_t** buffer);
 
     /*
@@ -135,7 +172,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*lockBuffer)(struct android_native_window_t* window,
+    int     (*lockBuffer)(struct ANativeWindow* window,
                 struct android_native_buffer_t* buffer);
    /*
     * hook called by EGL when modifications to the render buffer are done. 
@@ -145,7 +182,7 @@
     * 
     * Returns 0 on success or -errno on error.
     */
-    int     (*queueBuffer)(struct android_native_window_t* window,
+    int     (*queueBuffer)(struct ANativeWindow* window,
                 struct android_native_buffer_t* buffer);
 
     /*
@@ -153,13 +190,13 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*query)(struct android_native_window_t* window,
+    int     (*query)(struct ANativeWindow* window,
                 int what, int* value);
     
     /*
      * hook used to perform various operations on the surface.
      * (*perform)() is a generic mechanism to add functionality to
-     * android_native_window_t while keeping backward binary compatibility.
+     * ANativeWindow while keeping backward binary compatibility.
      * 
      * This hook should not be called directly, instead use the helper functions
      * defined below.
@@ -171,19 +208,26 @@
      *     NATIVE_WINDOW_SET_USAGE
      *     NATIVE_WINDOW_CONNECT
      *     NATIVE_WINDOW_DISCONNECT
+     *     NATIVE_WINDOW_SET_CROP
+     *     NATIVE_WINDOW_SET_BUFFER_COUNT
+     *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
+     *     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
      *  
      */
     
-    int     (*perform)(struct android_native_window_t* window,
+    int     (*perform)(struct ANativeWindow* window,
                 int operation, ... );
     
     void* reserved_proc[3];
-} android_native_window_t;
+};
 
+// Backwards compatibility...  please switch to ANativeWindow.
+typedef struct ANativeWindow android_native_window_t;
 
 /*
- *  native_window_set_usage() sets the intended usage flags for the next
- *  buffers acquired with (*lockBuffer)() and on.
+ *  native_window_set_usage(..., usage)
+ *  Sets the intended usage flags for the next buffers
+ *  acquired with (*lockBuffer)() and on.
  *  By default (if this function is never called), a usage of
  *      GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
  *  is assumed.
@@ -192,35 +236,96 @@
  */
 
 static inline int native_window_set_usage(
-        android_native_window_t* window, int usage)
+        ANativeWindow* window, int usage)
 {
     return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
 }
 
 /*
- * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made current.
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made current.
  * Returns -EINVAL if for some reason the window cannot be connected, which
  * can happen if it's connected to some other API.
  */
 static inline int native_window_connect(
-        android_native_window_t* window, int api)
+        ANativeWindow* window, int api)
 {
     return window->perform(window, NATIVE_WINDOW_CONNECT, api);
 }
 
 /*
- * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made not current.
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made not current.
  * An error is returned if for instance the window wasn't connected in the
  * first place.
  */
 static inline int native_window_disconnect(
-        android_native_window_t* window, int api)
+        ANativeWindow* window, int api)
 {
     return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
 }
 
+/*
+ * native_window_set_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
+ * A buffer's crop region is scaled to match the surface's size.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * if 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid,
+ * out of the buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_crop(
+        ANativeWindow* window,
+        android_native_rect_t const * crop)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
+}
+
+/*
+ * native_window_set_buffer_count(..., count)
+ * Sets the number of buffers associated with this native window.
+ */
+static inline int native_window_set_buffer_count(
+        ANativeWindow* window,
+        size_t bufferCount)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
+}
+
+/*
+ * native_window_set_buffers_geometry(..., int w, int h, int format)
+ * All buffers dequeued after this call will have the geometry specified.
+ * In particular, all buffers will have a fixed-size, independent form the
+ * native-window size. They will be appropriately scaled to the window-size
+ * upon composition.
+ *
+ * If all parameters are 0, the normal behavior is restored. That is,
+ * dequeued buffers following this call will be sized to the window's size.
+ *
+ */
+static inline int native_window_set_buffers_geometry(
+        ANativeWindow* window,
+        int w, int h, int format)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+            w, h, format);
+}
+
+/*
+ * native_window_set_buffers_transform(..., int transform)
+ * All buffers queued after this call will be displayed transformed according
+ * to the transform parameter specified.
+ */
+static inline int native_window_set_buffers_transform(
+        ANativeWindow* window,
+        int transform)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
+            transform);
+}
 
 // ---------------------------------------------------------------------------
 
@@ -263,6 +368,15 @@
 template <typename NATIVE_TYPE, typename TYPE, typename REF>
 class EGLNativeBase : public NATIVE_TYPE, public REF
 {
+public:
+    // Disambiguate between the incStrong in REF and NATIVE_TYPE
+    void incStrong(const void* id) const {
+        REF::incStrong(id);
+    }
+    void decStrong(const void* id) const {
+        REF::decStrong(id);
+    }
+
 protected:
     typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
     EGLNativeBase() : NATIVE_TYPE(), REF() {
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
index 5908bcc..2a09095 100644
--- a/include/utils/Asset.h
+++ b/include/utils/Asset.h
@@ -61,15 +61,6 @@
         ACCESS_BUFFER,
     } AccessMode;
 
-    enum {
-        /* data larger than this does not get uncompressed into a buffer */
-#ifdef HAVE_ANDROID_OS
-        UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
-#else
-        UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024
-#endif
-    };
-
     /*
      * Read data from the current offset.  Returns the actual number of
      * bytes read, 0 on EOF, or -1 on error.
@@ -317,6 +308,8 @@
     FileMap*    mMap;           // for memory-mapped input
     int         mFd;            // for file input
 
+    class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets
+
     unsigned char*  mBuf;       // for getBuffer()
 };
 
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
index d8994e0..9e2bf37 100644
--- a/include/utils/AssetManager.h
+++ b/include/utils/AssetManager.h
@@ -29,6 +29,24 @@
 #include <utils/ZipFileRO.h>
 #include <utils/threads.h>
 
+/*
+ * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AAssetManager { };
+
+#ifdef __cplusplus
+};
+#endif
+
+
+/*
+ * Now the proper C++ android-namespace definitions
+ */
+
 namespace android {
 
 class Asset;        // fwd decl for things that include Asset.h first
@@ -48,7 +66,7 @@
  * The asset hierarchy may be examined like a filesystem, using
  * AssetDir objects to peruse a single directory.
  */
-class AssetManager {
+class AssetManager : public AAssetManager {
 public:
     typedef enum CacheMode {
         CACHE_UNKNOWN = 0,
@@ -111,6 +129,8 @@
      */
     void setConfiguration(const ResTable_config& config, const char* locale = NULL);
 
+    void getConfiguration(ResTable_config* outConfig) const;
+
     typedef Asset::AccessMode AccessMode;       // typing shortcut
 
     /*
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
new file mode 100644
index 0000000..19c8bf0
--- /dev/null
+++ b/include/utils/BitSet.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef UTILS_BITSET_H
+#define UTILS_BITSET_H
+
+#include <stdint.h>
+
+/*
+ * Contains some bit manipulation helpers.
+ */
+
+namespace android {
+
+// A simple set of 32 bits that can be individually marked or cleared.
+struct BitSet32 {
+    uint32_t value;
+
+    inline BitSet32() : value(0) { }
+    explicit inline BitSet32(uint32_t value) : value(value) { }
+
+    // Gets the value associated with a particular bit index.
+    static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; }
+
+    // Clears the bit set.
+    inline void clear() { value = 0; }
+
+    // Returns true if the bit set does not contain any marked bits.
+    inline bool isEmpty() const { return ! value; }
+
+    // Returns true if the specified bit is marked.
+    inline bool hasBit(uint32_t n) const { return value & valueForBit(n); }
+
+    // Marks the specified bit.
+    inline void markBit(uint32_t n) { value |= valueForBit(n); }
+
+    // Clears the specified bit.
+    inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); }
+
+    // Finds the first marked bit in the set.
+    // Result is undefined if all bits are unmarked.
+    inline uint32_t firstMarkedBit() const { return __builtin_clz(value); }
+
+    // Finds the first unmarked bit in the set.
+    // Result is undefined if all bits are marked.
+    inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); }
+
+    inline bool operator== (const BitSet32& other) const { return value == other.value; }
+    inline bool operator!= (const BitSet32& other) const { return value != other.value; }
+};
+
+} // namespace android
+
+#endif // UTILS_BITSET_H
diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h
deleted file mode 100644
index 8e22b0f..0000000
--- a/include/utils/Buffer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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.
- */
-
-#ifndef __UTILS_BUFFER_H__
-#define __UTILS_BUFFER_H__ 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace android {
-
-class Buffer
-{
-private:
-    char *buf;
-    int bufsiz;
-    int used;
-    void ensureCapacity(int len);
-
-    void
-    makeRoomFor(int len)
-    {
-        if (len + used >= bufsiz) {
-            bufsiz = (len + used) * 3/2 + 2;
-            char *blah = new char[bufsiz];
-
-            memcpy(blah, buf, used);
-            delete[] buf;
-            buf = blah;
-        }
-    }
-    
-public:
-    Buffer()
-    {
-        bufsiz = 16;
-        buf = new char[bufsiz];
-        clear();
-    }
-
-    ~Buffer()
-    {
-       delete[] buf;
-    }
-
-    void
-    clear()
-    {
-        buf[0] = '\0';
-        used = 0;
-    }
-
-    int
-    length()
-    {
-        return used;
-    }
-
-    void
-    append(const char c)
-    {
-        makeRoomFor(1);
-        buf[used] = c;
-        used++;
-        buf[used] = '\0';
-    }
-
-    void
-    append(const char *s, int len)
-    {
-        makeRoomFor(len);
-
-        memcpy(buf + used, s, len);
-        used += len;
-        buf[used] = '\0';
-    }
-
-    void
-    append(const char *s)
-    {
-        append(s, strlen(s));
-    }
-
-    char *
-    getBytes()
-    {
-        return buf;
-    }
-};
-
-}; // namespace android
-
-#endif
diff --git a/include/utils/ObbFile.h b/include/utils/ObbFile.h
new file mode 100644
index 0000000..5243f50
--- /dev/null
+++ b/include/utils/ObbFile.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef OBBFILE_H_
+#define OBBFILE_H_
+
+#include <stdint.h>
+#include <strings.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// OBB flags (bit 0)
+#define OBB_OVERLAY         (1 << 0)
+
+class ObbFile : public RefBase {
+protected:
+    virtual ~ObbFile();
+
+public:
+    ObbFile();
+
+    bool readFrom(const char* filename);
+    bool readFrom(int fd);
+    bool writeTo(const char* filename);
+    bool writeTo(int fd);
+    bool removeFrom(const char* filename);
+    bool removeFrom(int fd);
+
+    const char* getFileName() const {
+        return mFileName;
+    }
+
+    const String8 getPackageName() const {
+        return mPackageName;
+    }
+
+    void setPackageName(String8 packageName) {
+        mPackageName = packageName;
+    }
+
+    int32_t getVersion() const {
+        return mVersion;
+    }
+
+    void setVersion(int32_t version) {
+        mVersion = version;
+    }
+
+    int32_t getFlags() const {
+        return mFlags;
+    }
+
+    void setFlags(int32_t flags) {
+        mFlags = flags;
+    }
+
+    bool isOverlay() {
+        return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
+    }
+
+    void setOverlay(bool overlay) {
+        if (overlay) {
+            mFlags |= OBB_OVERLAY;
+        } else {
+            mFlags &= ~OBB_OVERLAY;
+        }
+    }
+
+    static inline uint32_t get4LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+
+    static inline void put4LE(unsigned char* buf, uint32_t val) {
+        buf[0] = val & 0xFF;
+        buf[1] = (val >> 8) & 0xFF;
+        buf[2] = (val >> 16) & 0xFF;
+        buf[3] = (val >> 24) & 0xFF;
+    }
+
+private:
+    /* Package name this ObbFile is associated with */
+    String8 mPackageName;
+
+    /* Package version this ObbFile is associated with */
+    int32_t mVersion;
+
+    /* Flags for this OBB type. */
+    int32_t mFlags;
+
+    const char* mFileName;
+
+    size_t mFileSize;
+
+    size_t mFooterStart;
+
+    unsigned char* mReadBuf;
+
+    bool parseObbFile(int fd);
+};
+
+}
+#endif /* OBBFILE_H_ */
diff --git a/include/utils/PollLoop.h b/include/utils/PollLoop.h
new file mode 100644
index 0000000..bc616eb
--- /dev/null
+++ b/include/utils/PollLoop.h
@@ -0,0 +1,205 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef UTILS_POLL_LOOP_H
+#define UTILS_POLL_LOOP_H
+
+#include <utils/Vector.h>
+#include <utils/threads.h>
+
+#include <sys/poll.h>
+
+#include <android/looper.h>
+
+struct ALooper : public android::RefBase {
+protected:
+    virtual ~ALooper() { }
+
+public:
+    ALooper() { }
+};
+
+namespace android {
+
+/**
+ * A basic file descriptor polling loop based on poll() with callbacks.
+ */
+class PollLoop : public ALooper {
+protected:
+    virtual ~PollLoop();
+
+public:
+    PollLoop(bool allowNonCallbacks);
+
+    /**
+     * A callback that it to be invoked when an event occurs on a file descriptor.
+     * Specifies the events that were triggered and the user data provided when the
+     * callback was set.
+     *
+     * Returns true if the callback should be kept, false if it should be removed automatically
+     * after the callback returns.
+     */
+    typedef bool (*Callback)(int fd, int events, void* data);
+
+    enum {
+        POLL_CALLBACK = ALOOPER_POLL_CALLBACK,
+        POLL_TIMEOUT = ALOOPER_POLL_TIMEOUT,
+        POLL_ERROR = ALOOPER_POLL_ERROR,
+    };
+    
+    /**
+     * Performs a single call to poll() with optional timeout in milliseconds.
+     * Invokes callbacks for all file descriptors on which an event occurred.
+     *
+     * If the timeout is zero, returns immediately without blocking.
+     * If the timeout is negative, waits indefinitely until awoken.
+     *
+     * Returns ALOOPER_POLL_CALLBACK if a callback was invoked.
+     *
+     * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
+     * timeout expired.
+     *
+     * Returns ALOPER_POLL_ERROR if an error occurred.
+     *
+     * Returns a value >= 0 containing a file descriptor if it has data
+     * and it has no callback function (requiring the caller here to handle it).
+     * In this (and only this) case outEvents and outData will contain the poll
+     * events and data associated with the fd.
+     *
+     * This method must only be called on the thread owning the PollLoop.
+     * This method blocks until either a file descriptor is signalled, a timeout occurs,
+     * or wake() is called.
+     * This method does not return until it has finished invoking the appropriate callbacks
+     * for all file descriptors that were signalled.
+     */
+    int32_t pollOnce(int timeoutMillis, int* outEvents = NULL, void** outData = NULL);
+
+    /**
+     * Wakes the loop asynchronously.
+     *
+     * This method can be called on any thread.
+     * This method returns immediately.
+     */
+    void wake();
+
+    /**
+     * Control whether this PollLoop instance allows using IDs instead
+     * of callbacks.
+     */
+    bool getAllowNonCallbacks() const;
+    
+    /**
+     * Sets the callback for a file descriptor, replacing the existing one, if any.
+     * It is an error to call this method with events == 0 or callback == NULL.
+     *
+     * Note that a callback can be invoked with the POLLERR, POLLHUP or POLLNVAL events
+     * even if it is not explicitly requested when registered.
+     *
+     * This method can be called on any thread.
+     * This method may block briefly if it needs to wake the poll loop.
+     */
+    void setCallback(int fd, int ident, int events, Callback callback, void* data = NULL);
+
+    /**
+     * Convenience for above setCallback when ident is not used.  In this case
+     * the ident is set to POLL_CALLBACK.
+     */
+    void setCallback(int fd, int events, Callback callback, void* data = NULL);
+    
+    /**
+     * Like setCallback(), but for the NDK callback function.
+     */
+    void setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
+            void* data);
+    
+    /**
+     * Removes the callback for a file descriptor, if one exists.
+     *
+     * When this method returns, it is safe to close the file descriptor since the poll loop
+     * will no longer have a reference to it.  However, it is possible for the callback to
+     * already be running or for it to run one last time if the file descriptor was already
+     * signalled.  Calling code is responsible for ensuring that this case is safely handled.
+     * For example, if the callback takes care of removing itself during its own execution either
+     * by returning false or calling this method, then it can be guaranteed to not be invoked
+     * again at any later time unless registered anew.
+     *
+     * This method can be called on any thread.
+     * This method may block briefly if it needs to wake the poll loop.
+     *
+     * Returns true if a callback was actually removed, false if none was registered.
+     */
+    bool removeCallback(int fd);
+
+    /**
+     * Set the given PollLoop to be associated with the
+     * calling thread.  There must be a 1:1 relationship between
+     * PollLoop and thread.
+     */
+    static void setForThread(const sp<PollLoop>& pollLoop);
+    
+    /**
+     * Return the PollLoop associated with the calling thread.
+     */
+    static sp<PollLoop> getForThread();
+    
+private:
+    struct RequestedCallback {
+        Callback callback;
+        ALooper_callbackFunc* looperCallback;
+        int ident;
+        void* data;
+    };
+
+    struct PendingCallback {
+        int fd;
+        int ident;
+        int events;
+        Callback callback;
+        ALooper_callbackFunc* looperCallback;
+        void* data;
+    };
+    
+    const bool mAllowNonCallbacks;
+    
+    Mutex mLock;
+    bool mPolling;
+    uint32_t mWaiters;
+    Condition mAwake;
+    Condition mResume;
+
+    int mWakeReadPipeFd;
+    int mWakeWritePipeFd;
+
+    Vector<struct pollfd> mRequestedFds;
+    Vector<RequestedCallback> mRequestedCallbacks;
+
+    Vector<PendingCallback> mPendingCallbacks; // used privately by pollOnce
+    Vector<PendingCallback> mPendingFds;       // used privately by pollOnce
+    size_t mPendingFdsPos;
+    
+    void openWakePipe();
+    void closeWakePipe();
+
+    void setCallbackCommon(int fd, int ident, int events, Callback callback,
+            ALooper_callbackFunc* looperCallback, void* data);
+    ssize_t getRequestIndexLocked(int fd);
+    void wakeAndLock();
+    static void threadDestructor(void *st);
+};
+
+} // namespace android
+
+#endif // UTILS_POLL_LOOP_H
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
new file mode 100644
index 0000000..2ee768e
--- /dev/null
+++ b/include/utils/Pool.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef UTILS_POOL_H
+#define UTILS_POOL_H
+
+#include <utils/TypeHelpers.h>
+
+namespace android {
+
+class PoolImpl {
+public:
+    PoolImpl(size_t objSize);
+    ~PoolImpl();
+
+    void* allocImpl();
+    void freeImpl(void* obj);
+
+private:
+    size_t mObjSize;
+};
+
+/*
+ * A homogeneous typed memory pool for fixed size objects.
+ * Not intended to be thread-safe.
+ */
+template<typename T>
+class Pool : private PoolImpl {
+public:
+    /* Creates an initially empty pool. */
+    Pool() : PoolImpl(sizeof(T)) { }
+
+    /* Destroys the pool.
+     * Assumes that the pool is empty. */
+    ~Pool() { }
+
+    /* Allocates an object from the pool, growing the pool if needed. */
+    inline T* alloc() {
+        void* mem = allocImpl();
+        if (! traits<T>::has_trivial_ctor) {
+            return new (mem) T();
+        } else {
+            return static_cast<T*>(mem);
+        }
+    }
+
+    /* Frees an object from the pool. */
+    inline void free(T* obj) {
+        if (! traits<T>::has_trivial_dtor) {
+            obj->~T();
+        }
+        freeImpl(obj);
+    }
+};
+
+} // namespace android
+
+#endif // UTILS_POOL_H
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index bd7f28c..9c64ac0 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -333,9 +333,10 @@
 
 template<typename T>
 sp<T>& sp<T>::operator = (const sp<T>& other) {
-    if (other.m_ptr) other.m_ptr->incStrong(this);
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
     if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other.m_ptr;
+    m_ptr = otherPtr;
     return *this;
 }
 
@@ -351,9 +352,10 @@
 template<typename T> template<typename U>
 sp<T>& sp<T>::operator = (const sp<U>& other)
 {
-    if (other.m_ptr) other.m_ptr->incStrong(this);
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
     if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other.m_ptr;
+    m_ptr = otherPtr;
     return *this;
 }
 
@@ -466,10 +468,12 @@
 template<typename T>
 wp<T>& wp<T>::operator = (const wp<T>& other)
 {
-    if (other.m_ptr) other.m_refs->incWeak(this);
+    weakref_type* otherRefs(other.m_refs);
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.m_ptr;
-    m_refs = other.m_refs;
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
     return *this;
 }
 
@@ -478,8 +482,9 @@
 {
     weakref_type* newRefs =
         other != NULL ? other->createWeak(this) : 0;
+    T* otherPtr(other.m_ptr);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.get();
+    m_ptr = otherPtr;
     m_refs = newRefs;
     return *this;
 }
@@ -498,10 +503,12 @@
 template<typename T> template<typename U>
 wp<T>& wp<T>::operator = (const wp<U>& other)
 {
-    if (other.m_ptr) other.m_refs->incWeak(this);
+    weakref_type* otherRefs(other.m_refs);
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.m_ptr;
-    m_refs = other.m_refs;
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
     return *this;
 }
 
@@ -510,8 +517,9 @@
 {
     weakref_type* newRefs =
         other != NULL ? other->createWeak(this) : 0;
+    U* otherPtr(other.m_ptr);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.get();
+    m_ptr = otherPtr;
     m_refs = newRefs;
     return *this;
 }
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index b701ce7..da86da4 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -31,6 +31,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <android/configuration.h>
+
 namespace android {
 
 /** ********************************************************************
@@ -822,25 +824,25 @@
     };
     
     enum {
-        ORIENTATION_ANY  = 0x0000,
-        ORIENTATION_PORT = 0x0001,
-        ORIENTATION_LAND = 0x0002,
-        ORIENTATION_SQUARE = 0x0003,
+        ORIENTATION_ANY  = ACONFIGURATION_ORIENTATION_ANY,
+        ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,
+        ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,
+        ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,
     };
     
     enum {
-        TOUCHSCREEN_ANY  = 0x0000,
-        TOUCHSCREEN_NOTOUCH  = 0x0001,
-        TOUCHSCREEN_STYLUS  = 0x0002,
-        TOUCHSCREEN_FINGER  = 0x0003,
+        TOUCHSCREEN_ANY  = ACONFIGURATION_TOUCHSCREEN_ANY,
+        TOUCHSCREEN_NOTOUCH  = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,
+        TOUCHSCREEN_STYLUS  = ACONFIGURATION_TOUCHSCREEN_STYLUS,
+        TOUCHSCREEN_FINGER  = ACONFIGURATION_TOUCHSCREEN_FINGER,
     };
     
     enum {
-        DENSITY_DEFAULT = 0,
-        DENSITY_LOW = 120,
-        DENSITY_MEDIUM = 160,
-        DENSITY_HIGH = 240,
-        DENSITY_NONE = 0xffff
+        DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
+        DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
+        DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
+        DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
+        DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
     };
     
     union {
@@ -853,33 +855,34 @@
     };
     
     enum {
-        KEYBOARD_ANY  = 0x0000,
-        KEYBOARD_NOKEYS  = 0x0001,
-        KEYBOARD_QWERTY  = 0x0002,
-        KEYBOARD_12KEY  = 0x0003,
+        KEYBOARD_ANY  = ACONFIGURATION_KEYBOARD_ANY,
+        KEYBOARD_NOKEYS  = ACONFIGURATION_KEYBOARD_NOKEYS,
+        KEYBOARD_QWERTY  = ACONFIGURATION_KEYBOARD_QWERTY,
+        KEYBOARD_12KEY  = ACONFIGURATION_KEYBOARD_12KEY,
     };
     
     enum {
-        NAVIGATION_ANY  = 0x0000,
-        NAVIGATION_NONAV  = 0x0001,
-        NAVIGATION_DPAD  = 0x0002,
-        NAVIGATION_TRACKBALL  = 0x0003,
-        NAVIGATION_WHEEL  = 0x0004,
+        NAVIGATION_ANY  = ACONFIGURATION_NAVIGATION_ANY,
+        NAVIGATION_NONAV  = ACONFIGURATION_NAVIGATION_NONAV,
+        NAVIGATION_DPAD  = ACONFIGURATION_NAVIGATION_DPAD,
+        NAVIGATION_TRACKBALL  = ACONFIGURATION_NAVIGATION_TRACKBALL,
+        NAVIGATION_WHEEL  = ACONFIGURATION_NAVIGATION_WHEEL,
     };
     
     enum {
         MASK_KEYSHIDDEN = 0x0003,
-        KEYSHIDDEN_ANY = 0x0000,
-        KEYSHIDDEN_NO = 0x0001,
-        KEYSHIDDEN_YES = 0x0002,
-        KEYSHIDDEN_SOFT = 0x0003,
+        KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,
+        KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,
+        KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,
+        KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,
     };
     
     enum {
         MASK_NAVHIDDEN = 0x000c,
-        NAVHIDDEN_ANY = 0x0000,
-        NAVHIDDEN_NO = 0x0004,
-        NAVHIDDEN_YES = 0x0008,
+        SHIFT_NAVHIDDEN = 2,
+        NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,
+        NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,
+        NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,
     };
     
     union {
@@ -929,31 +932,34 @@
     enum {
         // screenLayout bits for screen size class.
         MASK_SCREENSIZE = 0x0f,
-        SCREENSIZE_ANY  = 0x00,
-        SCREENSIZE_SMALL = 0x01,
-        SCREENSIZE_NORMAL = 0x02,
-        SCREENSIZE_LARGE = 0x03,
+        SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,
+        SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,
+        SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,
+        SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,
+        SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,
         
         // screenLayout bits for wide/long screen variation.
         MASK_SCREENLONG = 0x30,
-        SCREENLONG_ANY = 0x00,
-        SCREENLONG_NO = 0x10,
-        SCREENLONG_YES = 0x20,
+        SHIFT_SCREENLONG = 4,
+        SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
+        SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
+        SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
     };
     
     enum {
         // uiMode bits for the mode type.
         MASK_UI_MODE_TYPE = 0x0f,
-        UI_MODE_TYPE_ANY = 0x00,
-        UI_MODE_TYPE_NORMAL = 0x01,
-        UI_MODE_TYPE_DESK = 0x02,
-        UI_MODE_TYPE_CAR = 0x03,
+        UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,
+        UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,
+        UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,
+        UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,
 
         // uiMode bits for the night switch.
         MASK_UI_MODE_NIGHT = 0x30,
-        UI_MODE_NIGHT_ANY = 0x00,
-        UI_MODE_NIGHT_NO = 0x10,
-        UI_MODE_NIGHT_YES = 0x20,
+        SHIFT_UI_MODE_NIGHT = 4,
+        UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,
+        UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,
+        UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,
     };
 
     union {
@@ -1022,19 +1028,19 @@
     // match the corresponding ones in android.content.pm.ActivityInfo and
     // attrs_manifest.xml.
     enum {
-        CONFIG_MCC = 0x0001,
-        CONFIG_MNC = 0x0002,
-        CONFIG_LOCALE = 0x0004,
-        CONFIG_TOUCHSCREEN = 0x0008,
-        CONFIG_KEYBOARD = 0x0010,
-        CONFIG_KEYBOARD_HIDDEN = 0x0020,
-        CONFIG_NAVIGATION = 0x0040,
-        CONFIG_ORIENTATION = 0x0080,
-        CONFIG_DENSITY = 0x0100,
-        CONFIG_SCREEN_SIZE = 0x0200,
-        CONFIG_VERSION = 0x0400,
-        CONFIG_SCREEN_LAYOUT = 0x0800,
-        CONFIG_UI_MODE = 0x1000
+        CONFIG_MCC = ACONFIGURATION_MCC,
+        CONFIG_MNC = ACONFIGURATION_MCC,
+        CONFIG_LOCALE = ACONFIGURATION_LOCALE,
+        CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,
+        CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,
+        CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,
+        CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,
+        CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
+        CONFIG_DENSITY = ACONFIGURATION_DENSITY,
+        CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
+        CONFIG_VERSION = ACONFIGURATION_VERSION,
+        CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
+        CONFIG_UI_MODE = ACONFIGURATION_UI_MODE
     };
     
     // Compare two configuration, returning CONFIG_* flags set for each value
@@ -1208,7 +1214,28 @@
             if (screenLayout || o.screenLayout) {
                 if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
                         && (requested->screenLayout & MASK_SCREENSIZE)) {
-                    return (screenLayout & MASK_SCREENSIZE);
+                    // A little backwards compatibility here: undefined is
+                    // considered equivalent to normal.  But only if the
+                    // requested size is at least normal; otherwise, small
+                    // is better than the default.
+                    int mySL = (screenLayout & MASK_SCREENSIZE);
+                    int oSL = (o.screenLayout & MASK_SCREENSIZE);
+                    int fixedMySL = mySL;
+                    int fixedOSL = oSL;
+                    if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+                        if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+                        if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+                    }
+                    // For screen size, the best match is the one that is
+                    // closest to the requested screen size, but not over
+                    // (the not over part is dealt with in match() below).
+                    if (fixedMySL == fixedOSL) {
+                        // If the two are the same, but 'this' is actually
+                        // undefined, then the other is really a better match.
+                        if (mySL == 0) return false;
+                        return true;
+                    }
+                    return fixedMySL >= fixedOSL;
                 }
                 if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
                         && (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1370,8 +1397,11 @@
         if (screenConfig != 0) {
             const int screenSize = screenLayout&MASK_SCREENSIZE;
             const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
-            if (setScreenSize != 0 && screenSize != 0
-                    && screenSize != setScreenSize) {
+            // Any screen sizes for larger screens than the setting do not
+            // match.
+            if ((setScreenSize != 0 && screenSize != 0
+                    && screenSize > setScreenSize) ||
+                    (setScreenSize == 0 && screenSize != 0)) {
                 return false;
             }
             
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index bc7626a..3b975b4 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -54,11 +54,13 @@
  * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
  * and avoid to have a copy of them in each compilation units Singleton<TYPE>
  * is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
  */
 
-#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)             \
-    template class Singleton< TYPE >;                       \
-    template< class TYPE > Mutex Singleton< TYPE >::sLock;  \
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \
+    template class Singleton< TYPE >;                           \
+    template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE);  \
     template<> TYPE* Singleton< TYPE >::sInstance(0);
 
 
diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h
index cc0bebc..693dd3c 100644
--- a/include/utils/StopWatch.h
+++ b/include/utils/StopWatch.h
@@ -37,6 +37,8 @@
         const char* name() const;
         nsecs_t     lap();
         nsecs_t     elapsedTime() const;
+
+        void        reset();
         
 private:
     const char*     mName;
diff --git a/include/utils/StreamingZipInflater.h b/include/utils/StreamingZipInflater.h
new file mode 100644
index 0000000..16867d8
--- /dev/null
+++ b/include/utils/StreamingZipInflater.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef __LIBS_STREAMINGZIPINFLATER_H
+#define __LIBS_STREAMINGZIPINFLATER_H
+
+#include <unistd.h>
+#include <inttypes.h>
+#include <zlib.h>
+
+namespace android {
+
+class StreamingZipInflater {
+public:
+    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;
+    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
+
+    // Flavor that pages in the compressed data from a fd
+    StreamingZipInflater(int fd, off_t compDataStart, size_t uncompSize, size_t compSize);
+
+    // Flavor that gets the compressed data from an in-memory buffer
+    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
+
+    ~StreamingZipInflater();
+
+    // read 'count' bytes of uncompressed data from the current position.  outBuf may
+    // be NULL, in which case the data is consumed and discarded.
+    ssize_t read(void* outBuf, size_t count);
+
+    // seeking backwards requires uncompressing fom the beginning, so is very
+    // expensive.  seeking forwards only requires uncompressing from the current
+    // position to the destination.
+    off_t seekAbsolute(off_t absoluteInputPosition);
+
+private:
+    void initInflateState();
+    int readNextChunk();
+
+    // where to find the uncompressed data
+    int mFd;
+    off_t mInFileStart;         // where the compressed data lives in the file
+    class FileMap* mDataMap;
+
+    z_stream mInflateState;
+    bool mStreamNeedsInit;
+
+    // output invariants for this asset
+    uint8_t* mOutBuf;           // output buf for decompressed bytes
+    size_t mOutBufSize;         // allocated size of mOutBuf
+    size_t mOutTotalSize;       // total uncompressed size of the blob
+
+    // current output state bookkeeping
+    off_t mOutCurPosition;      // current position in total offset
+    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf
+    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf
+
+    // input invariants
+    uint8_t* mInBuf;
+    size_t mInBufSize;          // allocated size of mInBuf;
+    size_t mInTotalSize;        // total size of compressed data for this blob
+
+    // input state bookkeeping
+    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies
+    // the z_stream contains state about input block consumption
+};
+
+}
+
+#endif
diff --git a/include/utils/String8.h b/include/utils/String8.h
index c4b18a4..ef0b51a 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -171,6 +171,9 @@
             status_t            append(const char* other);
             status_t            append(const char* other, size_t numChars);
 
+            status_t            appendFormat(const char* fmt, ...)
+                    __attribute__((format (printf, 2, 3)));
+
             // Note that this function takes O(N) time to calculate the value.
             // No cache value is stored.
             size_t              getUtf32Length() const;
@@ -372,7 +375,7 @@
 
 inline String8 String8::operator+(const String8& other) const
 {
-    String8 tmp;
+    String8 tmp(*this);
     tmp += other;
     return tmp;
 }
@@ -385,7 +388,7 @@
 
 inline String8 String8::operator+(const char* other) const
 {
-    String8 tmp;
+    String8 tmp(*this);
     tmp += other;
     return tmp;
 }
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index ad59fd6..ec851bd 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -114,13 +114,19 @@
             ssize_t         appendVector(const Vector<TYPE>& vector);
 
 
+    //! insert an array at a given index
+            ssize_t         insertArrayAt(const TYPE* array, size_t index, size_t length);
+
+    //! append an array at the end of this vector
+            ssize_t         appendArray(const TYPE* array, size_t length);
+
             /*! 
              * add/insert/replace items
              */
              
     //! insert one or several items initialized with their default constructor
     inline  ssize_t         insertAt(size_t index, size_t numItems = 1);
-    //! insert on onr several items initialized from a prototype item
+    //! insert one or several items initialized from a prototype item
             ssize_t         insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
     //! pop the top of the stack (removes the last element). No-op if the stack's empty
     inline  void            pop();
@@ -259,6 +265,16 @@
 }
 
 template<class TYPE> inline
+ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) {
+    return VectorImpl::insertArrayAt(array, index, length);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) {
+    return VectorImpl::appendArray(array, length);
+}
+
+template<class TYPE> inline
 ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
     return VectorImpl::insertAt(&item, index, numItems);
 }
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index 49b03f1..c4ec2ff 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -65,9 +65,11 @@
             size_t          capacity() const;
             ssize_t         setCapacity(size_t size);
 
-            /*! append/insert another vector */
+            /*! append/insert another vector or array */
             ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
             ssize_t         appendVector(const VectorImpl& vector);
+            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);
+            ssize_t         appendArray(const void* array, size_t length);
             
             /*! add/insert/replace items */
             ssize_t         insertAt(size_t where, size_t numItems = 1);
@@ -184,6 +186,8 @@
             void            push(const void* item);
             ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
             ssize_t         appendVector(const VectorImpl& vector);
+            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);
+            ssize_t         appendArray(const void* array, size_t length);
             ssize_t         insertAt(size_t where, size_t numItems = 1);
             ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);
             ssize_t         replaceAt(size_t index);
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
index 30e0036..e38bf66 100644
--- a/include/utils/ZipFileCRO.h
+++ b/include/utils/ZipFileCRO.h
@@ -47,8 +47,8 @@
         const char* fileName);
 
 extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
-        int* pMethod, long* pUncompLen,
-        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+        int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
 
 extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
 
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
index 51c4f2f..97d31f4 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -58,14 +58,19 @@
 class ZipFileRO {
 public:
     ZipFileRO()
-        : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+        : mFd(-1), mFileName(NULL), mFileLength(-1),
+          mDirectoryMap(NULL),
+          mNumEntries(-1), mDirectoryOffset(-1),
+          mHashTableSize(-1), mHashTable(NULL)
         {}
     ~ZipFileRO() {
         free(mHashTable);
-        if (mFileMap)
-            mFileMap->release();
+        if (mDirectoryMap)
+            mDirectoryMap->release();
         if (mFd >= 0)
             close(mFd);
+        if (mFileName)
+            free(mFileName);
     }
 
     /*
@@ -118,8 +123,8 @@
      * Returns "false" if "entry" is bogus or if the data in the Zip file
      * appears to be bad.
      */
-    bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
-        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
 
     /*
      * Create a new FileMap object that maps a subset of the archive.  For
@@ -155,13 +160,13 @@
      * Utility function: uncompress deflated data, buffer to buffer.
      */
     static bool inflateBuffer(void* outBuf, const void* inBuf,
-        long uncompLen, long compLen);
+        size_t uncompLen, size_t compLen);
 
     /*
      * Utility function: uncompress deflated data, buffer to fd.
      */
     static bool inflateBuffer(int fd, const void* inBuf,
-        long uncompLen, long compLen);
+        size_t uncompLen, size_t compLen);
 
     /*
      * Some basic functions for raw data manipulation.  "LE" means
@@ -179,6 +184,9 @@
     ZipFileRO(const ZipFileRO& src);
     ZipFileRO& operator=(const ZipFileRO& src);
 
+    /* locate and parse the central directory */
+    bool mapCentralDirectory(void);
+
     /* parse the archive, prepping internal structures */
     bool parseZipArchive(void);
 
@@ -203,12 +211,21 @@
     /* open Zip archive */
     int         mFd;
 
+    /* zip file name */
+    char*       mFileName;
+
+    /* length of file */
+    size_t      mFileLength;
+
     /* mapped file */
-    FileMap*    mFileMap;
+    FileMap*    mDirectoryMap;
 
     /* number of entries in the Zip archive */
     int         mNumEntries;
 
+    /* CD directory offset in the Zip archive */
+    off_t       mDirectoryOffset;
+
     /*
      * We know how many entries are in the Zip archive, so we have a
      * fixed-size hash table.  We probe for an empty slot.
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 5ac0c5e..1bcfaed 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -295,6 +295,96 @@
 
 /*****************************************************************************/
 
+#if defined(HAVE_PTHREADS)
+
+/*
+ * Simple mutex class.  The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it.  They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class RWLock {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+
+                RWLock();
+                RWLock(const char* name);
+                RWLock(int type, const char* name = NULL);
+                ~RWLock();
+
+    status_t    readLock();
+    status_t    tryReadLock();
+    status_t    writeLock();
+    status_t    tryWriteLock();
+    void        unlock();
+
+    class AutoRLock {
+    public:
+        inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
+        inline ~AutoRLock() { mLock.unlock(); }
+    private:
+        RWLock& mLock;
+    };
+
+    class AutoWLock {
+    public:
+        inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
+        inline ~AutoWLock() { mLock.unlock(); }
+    private:
+        RWLock& mLock;
+    };
+
+private:
+    // A RWLock cannot be copied
+                RWLock(const RWLock&);
+   RWLock&      operator = (const RWLock&);
+
+   pthread_rwlock_t mRWLock;
+};
+
+inline RWLock::RWLock() {
+    pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(const char* name) {
+    pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(int type, const char* name) {
+    if (type == SHARED) {
+        pthread_rwlockattr_t attr;
+        pthread_rwlockattr_init(&attr);
+        pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_rwlock_init(&mRWLock, &attr);
+        pthread_rwlockattr_destroy(&attr);
+    } else {
+        pthread_rwlock_init(&mRWLock, NULL);
+    }
+}
+inline RWLock::~RWLock() {
+    pthread_rwlock_destroy(&mRWLock);
+}
+inline status_t RWLock::readLock() {
+    return -pthread_rwlock_rdlock(&mRWLock);
+}
+inline status_t RWLock::tryReadLock() {
+    return -pthread_rwlock_tryrdlock(&mRWLock);
+}
+inline status_t RWLock::writeLock() {
+    return -pthread_rwlock_wrlock(&mRWLock);
+}
+inline status_t RWLock::tryWriteLock() {
+    return -pthread_rwlock_trywrlock(&mRWLock);
+}
+inline void RWLock::unlock() {
+    pthread_rwlock_unlock(&mRWLock);
+}
+
+#endif // HAVE_PTHREADS
+
+/*****************************************************************************/
+
 /*
  * Condition variable class.  The implementation is system-dependent.
  *
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 0016503..a3e117f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -367,6 +367,26 @@
     return token;
 }
 
+void IPCThreadState::setStrictModePolicy(int32_t policy)
+{
+    mStrictModePolicy = policy;
+}
+
+int32_t IPCThreadState::getStrictModePolicy() const
+{
+    return mStrictModePolicy;
+}
+
+void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
+{
+    mLastTransactionBinderFlags = flags;
+}
+
+int32_t IPCThreadState::getLastTransactionBinderFlags() const
+{
+    return mLastTransactionBinderFlags;
+}
+
 void IPCThreadState::restoreCallingIdentity(int64_t token)
 {
     mCallingUid = (int)(token>>32);
@@ -588,7 +608,10 @@
 }
 
 IPCThreadState::IPCThreadState()
-    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
+    : mProcess(ProcessState::self()),
+      mMyThreadId(androidGetTid()),
+      mStrictModePolicy(0),
+      mLastTransactionBinderFlags(0)
 {
     pthread_setspecific(gTLS, this);
     clearCaller();
@@ -972,11 +995,11 @@
             }
             if (tr.target.ptr) {
                 sp<BBinder> b((BBinder*)tr.cookie);
-                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
                 if (error < NO_ERROR) reply.setError(error);
-                
+
             } else {
-                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
                 if (error < NO_ERROR) reply.setError(error);
             }
             
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index bff4c9b..e13036f 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -36,7 +36,7 @@
         : BpInterface<IPermissionController>(impl)
     {
     }
-        
+
     virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
     {
         Parcel data, reply;
@@ -46,7 +46,7 @@
         data.writeInt32(uid);
         remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
         // fail on exception
-        if (reply.readInt32() != 0) return 0;
+        if (reply.readExceptionCode() != 0) return 0;
         return reply.readInt32() != 0;
     }
 };
@@ -66,8 +66,7 @@
             int32_t pid = data.readInt32();
             int32_t uid = data.readInt32();
             bool res = checkPermission(permission, pid, uid);
-            // write exception
-            reply->writeInt32(0);
+            reply->writeNoException();
             reply->writeInt32(res ? 1 : 0);
             return NO_ERROR;
         } break;
@@ -77,4 +76,3 @@
 }
 
 }; // namespace android
-
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 0cf4158..1fa4c35 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -129,19 +129,19 @@
         : BpInterface<IServiceManager>(impl)
     {
     }
-        
+
     virtual sp<IBinder> getService(const String16& name) const
     {
         unsigned n;
         for (n = 0; n < 5; n++){
             sp<IBinder> svc = checkService(name);
             if (svc != NULL) return svc;
-            LOGI("Waiting for sevice %s...\n", String8(name).string());
+            LOGI("Waiting for service %s...\n", String8(name).string());
             sleep(1);
         }
         return NULL;
     }
-    
+
     virtual sp<IBinder> checkService( const String16& name) const
     {
         Parcel data, reply;
@@ -158,7 +158,7 @@
         data.writeString16(name);
         data.writeStrongBinder(service);
         status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
-        return err == NO_ERROR ? reply.readInt32() : err;
+        return err == NO_ERROR ? reply.readExceptionCode() : err;
     }
 
     virtual Vector<String16> listServices()
@@ -226,4 +226,3 @@
 }
 
 }; // namespace android
-
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 00d2210..f329ac4 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -19,6 +19,7 @@
 
 #include <binder/Parcel.h>
 
+#include <binder/IPCThreadState.h>
 #include <binder/Binder.h>
 #include <binder/BpBinder.h>
 #include <utils/Debug.h>
@@ -47,6 +48,12 @@
 
 #define PAD_SIZE(s) (((s)+3)&~3)
 
+// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
+#define STRICT_MODE_PENALTY_GATHER 0x100
+
+// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
+#define EX_HAS_REPLY_HEADER -128
+
 // XXX This can be made public if we want to provide
 // support for typed data.
 struct small_flat_data
@@ -436,19 +443,37 @@
     return mHasFds;
 }
 
+// Write RPC headers.  (previously just the interface token)
 status_t Parcel::writeInterfaceToken(const String16& interface)
 {
+    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
+               STRICT_MODE_PENALTY_GATHER);
     // currently the interface identification token is just its name as a string
     return writeString16(interface);
 }
 
 bool Parcel::checkInterface(IBinder* binder) const
 {
-    return enforceInterface(binder->getInterfaceDescriptor()); 
+    return enforceInterface(binder->getInterfaceDescriptor());
 }
 
-bool Parcel::enforceInterface(const String16& interface) const
+bool Parcel::enforceInterface(const String16& interface,
+                              IPCThreadState* threadState) const
 {
+    int32_t strictPolicy = readInt32();
+    if (threadState == NULL) {
+        threadState = IPCThreadState::self();
+    }
+    if ((threadState->getLastTransactionBinderFlags() &
+         IBinder::FLAG_ONEWAY) != 0) {
+      // For one-way calls, the callee is running entirely
+      // disconnected from the caller, so disable StrictMode entirely.
+      // Not only does disk/network usage not impact the caller, but
+      // there's no way to commuicate back any violations anyway.
+      threadState->setStrictModePolicy(0);
+    } else {
+      threadState->setStrictModePolicy(strictPolicy);
+    }
     const String16 str(readString16());
     if (str == interface) {
         return true;
@@ -457,7 +482,7 @@
                 String8(interface).string(), String8(str).string());
         return false;
     }
-} 
+}
 
 const size_t* Parcel::objects() const
 {
@@ -750,6 +775,11 @@
     goto restart_write;
 }
 
+status_t Parcel::writeNoException()
+{
+    return writeInt32(0);
+}
+
 void Parcel::remove(size_t start, size_t amt)
 {
     LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
@@ -938,6 +968,20 @@
     return val;
 }
 
+int32_t Parcel::readExceptionCode() const
+{
+  int32_t exception_code = readAligned<int32_t>();
+  if (exception_code == EX_HAS_REPLY_HEADER) {
+    int32_t header_size = readAligned<int32_t>();
+    // Skip over fat responses headers.  Not used (or propagated) in
+    // native code
+    setDataPosition(dataPosition() + header_size);
+    // And fat response headers are currently only used when there are no
+    // exceptions, so return no error:
+    return 0;
+  }
+  return exception_code;
+}
 
 native_handle* Parcel::readNativeHandle() const
 {
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
new file mode 100644
index 0000000..249558a
--- /dev/null
+++ b/libs/gui/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	ISensorEventConnection.cpp \
+	ISensorServer.cpp \
+	Sensor.cpp \
+	SensorChannel.cpp \
+	SensorEventQueue.cpp \
+	SensorManager.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libhardware \
+	libhardware_legacy
+
+LOCAL_MODULE:= libgui
+
+ifeq ($(TARGET_SIMULATOR),true)
+    LOCAL_LDLIBS += -lpthread
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
new file mode 100644
index 0000000..a5083fe
--- /dev/null
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/ISensorEventConnection.h>
+#include <gui/SensorChannel.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
+    ENABLE_DISABLE,
+    SET_EVENT_RATE
+};
+
+class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
+{
+public:
+    BpSensorEventConnection(const sp<IBinder>& impl)
+        : BpInterface<ISensorEventConnection>(impl)
+    {
+    }
+
+    virtual sp<SensorChannel> getSensorChannel() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        remote()->transact(GET_SENSOR_CHANNEL, data, &reply);
+        return new SensorChannel(reply);
+    }
+
+    virtual status_t enableDisable(int handle, bool enabled)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt32(enabled);
+        remote()->transact(ENABLE_DISABLE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setEventRate(int handle, nsecs_t ns)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt64(ns);
+        remote()->transact(SET_EVENT_RATE, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
+
+// ----------------------------------------------------------------------------
+
+status_t BnSensorEventConnection::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_SENSOR_CHANNEL: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            sp<SensorChannel> channel(getSensorChannel());
+            channel->writeToParcel(reply);
+            return NO_ERROR;
+        } break;
+        case ENABLE_DISABLE: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            int enabled = data.readInt32();
+            status_t result = enableDisable(handle, enabled);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case SET_EVENT_RATE: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            int ns = data.readInt64();
+            status_t result = setEventRate(handle, ns);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
new file mode 100644
index 0000000..7111092
--- /dev/null
+++ b/libs/gui/ISensorServer.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/Sensor.h>
+#include <gui/ISensorServer.h>
+#include <gui/ISensorEventConnection.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
+    CREATE_SENSOR_EVENT_CONNECTION,
+};
+
+class BpSensorServer : public BpInterface<ISensorServer>
+{
+public:
+    BpSensorServer(const sp<IBinder>& impl)
+        : BpInterface<ISensorServer>(impl)
+    {
+    }
+
+    virtual Vector<Sensor> getSensorList()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        remote()->transact(GET_SENSOR_LIST, data, &reply);
+        Sensor s;
+        Vector<Sensor> v;
+        int32_t n = reply.readInt32();
+        v.setCapacity(n);
+        while (n--) {
+            reply.read(static_cast<Flattenable&>(s));
+            v.add(s);
+        }
+        return v;
+    }
+
+    virtual sp<ISensorEventConnection> createSensorEventConnection()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
+        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
+
+// ----------------------------------------------------------------------
+
+status_t BnSensorServer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_SENSOR_LIST: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            Vector<Sensor> v(getSensorList());
+            size_t n = v.size();
+            reply->writeInt32(n);
+            for (size_t i=0 ; i<n ; i++) {
+                reply->write(static_cast<const Flattenable&>(v[i]));
+            }
+            return NO_ERROR;
+        } break;
+        case CREATE_SENSOR_EVENT_CONNECTION: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            sp<ISensorEventConnection> connection(createSensorEventConnection());
+            reply->writeStrongBinder(connection->asBinder());
+            return NO_ERROR;
+        } break;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
new file mode 100644
index 0000000..b1f37ff
--- /dev/null
+++ b/libs/gui/Sensor.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Flattenable.h>
+
+#include <hardware/sensors.h>
+
+#include <gui/Sensor.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+Sensor::Sensor()
+    : mHandle(0), mType(0),
+      mMinValue(0), mMaxValue(0), mResolution(0),
+      mPower(0), mMinDelay(0)
+{
+}
+
+Sensor::Sensor(struct sensor_t const* hwSensor)
+{
+    mName = hwSensor->name;
+    mVendor = hwSensor->vendor;
+    mHandle = hwSensor->handle;
+    mType = hwSensor->type;
+    mMinValue = 0;                      // FIXME: minValue
+    mMaxValue = hwSensor->maxRange;     // FIXME: maxValue
+    mResolution = hwSensor->resolution;
+    mPower = hwSensor->power;
+    mMinDelay = hwSensor->minDelay;
+}
+
+Sensor::~Sensor()
+{
+}
+
+const String8& Sensor::getName() const {
+    return mName;
+}
+
+const String8& Sensor::getVendor() const {
+    return mVendor;
+}
+
+int32_t Sensor::getHandle() const {
+    return mHandle;
+}
+
+int32_t Sensor::getType() const {
+    return mType;
+}
+
+float Sensor::getMinValue() const {
+    return mMinValue;
+}
+
+float Sensor::getMaxValue() const {
+    return mMaxValue;
+}
+
+float Sensor::getResolution() const {
+    return mResolution;
+}
+
+float Sensor::getPowerUsage() const {
+    return mPower;
+}
+
+int32_t Sensor::getMinDelay() const {
+    return mMinDelay;
+}
+
+size_t Sensor::getFlattenedSize() const
+{
+    return  sizeof(int32_t) + ((mName.length() + 3) & ~3) +
+            sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
+            sizeof(int32_t) * 2 +
+            sizeof(float) * 4 +
+            sizeof(int32_t);
+}
+
+size_t Sensor::getFdCount() const
+{
+    return 0;
+}
+
+static inline
+size_t write(void* buffer, size_t offset, const String8& value) {
+    memcpy(static_cast<char*>(buffer) + offset, value.string(), value.length());
+    return (value.length() + 3) & ~3;
+}
+
+static inline
+size_t write(void* buffer, size_t offset, float value) {
+    *reinterpret_cast<float*>(static_cast<char*>(buffer) + offset) = value;
+    return sizeof(float);
+}
+
+static inline
+size_t write(void* buffer, size_t offset, int32_t value) {
+    *reinterpret_cast<int32_t*>(static_cast<char*>(buffer) + offset) = value;
+    return sizeof(int32_t);
+}
+
+status_t Sensor::flatten(void* buffer, size_t size,
+        int fds[], size_t count) const
+{
+    if (size < Sensor::getFlattenedSize())
+        return -ENOMEM;
+
+    size_t offset = 0;
+    offset += write(buffer, offset, int32_t(mName.length()));
+    offset += write(buffer, offset, mName);
+    offset += write(buffer, offset, int32_t(mVendor.length()));
+    offset += write(buffer, offset, mVendor);
+    offset += write(buffer, offset, mHandle);
+    offset += write(buffer, offset, mType);
+    offset += write(buffer, offset, mMinValue);
+    offset += write(buffer, offset, mMaxValue);
+    offset += write(buffer, offset, mResolution);
+    offset += write(buffer, offset, mPower);
+    offset += write(buffer, offset, mMinDelay);
+
+    return NO_ERROR;
+}
+
+static inline
+size_t read(void const* buffer, size_t offset, String8* value, int32_t len) {
+    value->setTo(static_cast<char const*>(buffer) + offset, len);
+    return (len + 3) & ~3;
+}
+
+static inline
+size_t read(void const* buffer, size_t offset, float* value) {
+    *value = *reinterpret_cast<float const*>(static_cast<char const*>(buffer) + offset);
+    return sizeof(float);
+}
+
+static inline
+size_t read(void const* buffer, size_t offset, int32_t* value) {
+    *value = *reinterpret_cast<int32_t const*>(static_cast<char const*>(buffer) + offset);
+    return sizeof(int32_t);
+}
+
+status_t Sensor::unflatten(void const* buffer, size_t size,
+        int fds[], size_t count)
+{
+    int32_t len;
+    size_t offset = 0;
+    offset += read(buffer, offset, &len);
+    offset += read(buffer, offset, &mName, len);
+    offset += read(buffer, offset, &len);
+    offset += read(buffer, offset, &mVendor, len);
+    offset += read(buffer, offset, &mHandle);
+    offset += read(buffer, offset, &mType);
+    offset += read(buffer, offset, &mMinValue);
+    offset += read(buffer, offset, &mMaxValue);
+    offset += read(buffer, offset, &mResolution);
+    offset += read(buffer, offset, &mPower);
+    offset += read(buffer, offset, &mMinDelay);
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/SensorChannel.cpp b/libs/gui/SensorChannel.cpp
new file mode 100644
index 0000000..147e1c2
--- /dev/null
+++ b/libs/gui/SensorChannel.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <utils/Errors.h>
+
+#include <binder/Parcel.h>
+
+#include <gui/SensorChannel.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+SensorChannel::SensorChannel()
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    int fds[2];
+    if (pipe(fds) == 0) {
+        mReceiveFd = fds[0];
+        mSendFd = fds[1];
+        fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
+        fcntl(mSendFd, F_SETFL, O_NONBLOCK);
+    }
+}
+
+SensorChannel::SensorChannel(const Parcel& data)
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    mReceiveFd = dup(data.readFileDescriptor());
+    fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
+}
+
+SensorChannel::~SensorChannel()
+{
+    if (mSendFd >= 0)
+        close(mSendFd);
+
+    if (mReceiveFd >= 0)
+        close(mReceiveFd);
+}
+
+int SensorChannel::getFd() const
+{
+    return mReceiveFd;
+}
+
+ssize_t SensorChannel::write(void const* vaddr, size_t size)
+{
+    ssize_t len = ::write(mSendFd, vaddr, size);
+    if (len < 0)
+        return -errno;
+    return len;
+}
+
+ssize_t SensorChannel::read(void* vaddr, size_t size)
+{
+    ssize_t len = ::read(mReceiveFd, vaddr, size);
+    if (len < 0)
+        return -errno;
+    return len;
+}
+
+status_t SensorChannel::writeToParcel(Parcel* reply) const
+{
+    if (mReceiveFd < 0)
+        return -EINVAL;
+
+    status_t result = reply->writeDupFileDescriptor(mReceiveFd);
+    close(mReceiveFd);
+    mReceiveFd = -1;
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
new file mode 100644
index 0000000..7eb6da5
--- /dev/null
+++ b/libs/gui/SensorEventQueue.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "Sensors"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/PollLoop.h>
+
+#include <gui/Sensor.h>
+#include <gui/SensorChannel.h>
+#include <gui/SensorEventQueue.h>
+#include <gui/ISensorEventConnection.h>
+
+#include <android/sensor.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+SensorEventQueue::SensorEventQueue(const sp<ISensorEventConnection>& connection)
+    : mSensorEventConnection(connection)
+{
+}
+
+SensorEventQueue::~SensorEventQueue()
+{
+}
+
+void SensorEventQueue::onFirstRef()
+{
+    mSensorChannel = mSensorEventConnection->getSensorChannel();
+}
+
+int SensorEventQueue::getFd() const
+{
+    return mSensorChannel->getFd();
+}
+
+ssize_t SensorEventQueue::write(ASensorEvent const* events, size_t numEvents)
+{
+    ssize_t size = mSensorChannel->write(events, numEvents * sizeof(events[0]));
+    if (size >= 0) {
+        if (size % sizeof(events[0])) {
+            // partial write!!! should never happen.
+            return -EINVAL;
+        }
+        // returns number of events written
+        size /= sizeof(events[0]);
+    }
+    return size;
+}
+
+ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents)
+{
+    ssize_t size = mSensorChannel->read(events, numEvents*sizeof(events[0]));
+    if (size >= 0) {
+        if (size % sizeof(events[0])) {
+            // partial read!!! should never happen.
+            return -EINVAL;
+        }
+        // returns number of events read
+        size /= sizeof(events[0]);
+    }
+    return size;
+}
+
+sp<PollLoop> SensorEventQueue::getPollLoop() const
+{
+    Mutex::Autolock _l(mLock);
+    if (mPollLoop == 0) {
+        mPollLoop = new PollLoop(true);
+        mPollLoop->setCallback(getFd(), getFd(), POLLIN, NULL, NULL);
+    }
+    return mPollLoop;
+}
+
+status_t SensorEventQueue::waitForEvent() const
+{
+    const int fd = getFd();
+    sp<PollLoop> pollLoop(getPollLoop());
+    int32_t result = pollLoop->pollOnce(-1, NULL, NULL);
+    return (result == fd) ? NO_ERROR : -1;
+}
+
+status_t SensorEventQueue::wake() const
+{
+    sp<PollLoop> pollLoop(getPollLoop());
+    pollLoop->wake();
+    return NO_ERROR;
+}
+
+status_t SensorEventQueue::enableSensor(Sensor const* sensor) const {
+    return mSensorEventConnection->enableDisable(sensor->getHandle(), true);
+}
+
+status_t SensorEventQueue::disableSensor(Sensor const* sensor) const {
+    return mSensorEventConnection->enableDisable(sensor->getHandle(), false);
+}
+
+status_t SensorEventQueue::enableSensor(int32_t handle, int32_t us) const {
+    status_t err = mSensorEventConnection->enableDisable(handle, true);
+    if (err == NO_ERROR) {
+        mSensorEventConnection->setEventRate(handle, us2ns(us));
+    }
+    return err;
+}
+
+status_t SensorEventQueue::disableSensor(int32_t handle) const {
+    return mSensorEventConnection->enableDisable(handle, false);
+}
+
+status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const {
+    return mSensorEventConnection->setEventRate(sensor->getHandle(), ns);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
new file mode 100644
index 0000000..d719efb
--- /dev/null
+++ b/libs/gui/SensorManager.cpp
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "Sensors"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Singleton.h>
+
+#include <binder/IServiceManager.h>
+
+#include <gui/ISensorServer.h>
+#include <gui/ISensorEventConnection.h>
+#include <gui/Sensor.h>
+#include <gui/SensorManager.h>
+#include <gui/SensorEventQueue.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE(SensorManager)
+
+SensorManager::SensorManager()
+    : mSensorList(0)
+{
+    const String16 name("sensorservice");
+    while (getService(name, &mSensorServer) != NO_ERROR) {
+        usleep(250000);
+    }
+
+    mSensors = mSensorServer->getSensorList();
+    size_t count = mSensors.size();
+    mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
+    for (size_t i=0 ; i<count ; i++) {
+        mSensorList[i] = mSensors.array() + i;
+    }
+}
+
+SensorManager::~SensorManager()
+{
+    free(mSensorList);
+}
+
+ssize_t SensorManager::getSensorList(Sensor const* const** list) const
+{
+    *list = mSensorList;
+    return mSensors.size();
+}
+
+Sensor const* SensorManager::getDefaultSensor(int type)
+{
+    // For now we just return the first sensor of that type we find.
+    // in the future it will make sense to let the SensorService make
+    // that decision.
+    for (size_t i=0 ; i<mSensors.size() ; i++) {
+        if (mSensorList[i]->getType() == type)
+            return mSensorList[i];
+    }
+    return NULL;
+}
+
+sp<SensorEventQueue> SensorManager::createEventQueue()
+{
+    sp<SensorEventQueue> result = new SensorEventQueue(
+            mSensorServer->createSensorEventConnection());
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
index fe85b34..ce3c71a 100644
--- a/libs/surfaceflinger_client/Android.mk
+++ b/libs/surfaceflinger_client/Android.mk
@@ -4,7 +4,7 @@
 LOCAL_SRC_FILES:= \
 	ISurfaceComposer.cpp \
 	ISurface.cpp \
-	ISurfaceFlingerClient.cpp \
+	ISurfaceComposerClient.cpp \
 	LayerState.cpp \
 	SharedBufferStack.cpp \
 	Surface.cpp \
diff --git a/libs/surfaceflinger_client/ISurface.cpp b/libs/surfaceflinger_client/ISurface.cpp
index bb86199..7049d9e 100644
--- a/libs/surfaceflinger_client/ISurface.cpp
+++ b/libs/surfaceflinger_client/ISurface.cpp
@@ -71,11 +71,15 @@
     {
     }
 
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage)
+    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
     {
         Parcel data, reply;
         data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
         data.writeInt32(bufferIdx);
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
         data.writeInt32(usage);
         remote()->transact(REQUEST_BUFFER, data, &reply);
         sp<GraphicBuffer> buffer = new GraphicBuffer();
@@ -83,6 +87,16 @@
         return buffer;
     }
 
+    virtual status_t setBufferCount(int bufferCount)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurface::getInterfaceDescriptor());
+        data.writeInt32(bufferCount);
+        remote()->transact(SET_BUFFER_COUNT, data, &reply);
+        status_t err = reply.readInt32();
+        return err;
+    }
+
     virtual status_t registerBuffers(const BufferHeap& buffers)
     {
         Parcel data, reply;
@@ -140,12 +154,22 @@
         case REQUEST_BUFFER: {
             CHECK_INTERFACE(ISurface, data, reply);
             int bufferIdx = data.readInt32();
-            int usage = data.readInt32();
-            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
+            uint32_t w = data.readInt32();
+            uint32_t h = data.readInt32();
+            uint32_t format = data.readInt32();
+            uint32_t usage = data.readInt32();
+            sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, w, h, format, usage));
             if (buffer == NULL)
                 return BAD_VALUE;
             return reply->write(*buffer);
         }
+        case SET_BUFFER_COUNT: {
+            CHECK_INTERFACE(ISurface, data, reply);
+            int bufferCount = data.readInt32();
+            status_t err = setBufferCount(bufferCount);
+            reply->writeInt32(err);
+            return NO_ERROR;
+        }
         case REGISTER_BUFFERS: {
             CHECK_INTERFACE(ISurface, data, reply);
             BufferHeap buffer;
diff --git a/libs/surfaceflinger_client/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
index b6f4e24..5c111f6 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -46,13 +46,22 @@
     {
     }
 
-    virtual sp<ISurfaceFlingerClient> createConnection()
+    virtual sp<ISurfaceComposerClient> createConnection()
     {
         uint32_t n;
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
-        return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
+        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
+    }
+
+    virtual sp<ISurfaceComposerClient> createClientConnection()
+    {
+        uint32_t n;
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CREATE_CLIENT_CONNECTION, data, &reply);
+        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
     virtual sp<IMemoryHeap> getCblk() const
@@ -136,6 +145,11 @@
             sp<IBinder> b = createConnection()->asBinder();
             reply->writeStrongBinder(b);
         } break;
+        case CREATE_CLIENT_CONNECTION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> b = createClientConnection()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
         case OPEN_GLOBAL_TRANSACTION: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             openGlobalTransaction();
diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
new file mode 100644
index 0000000..2cc1f8e
--- /dev/null
+++ b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 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.
+ */
+
+// tag as surfaceflinger
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <private/surfaceflinger/LayerState.h>
+
+// ---------------------------------------------------------------------------
+
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+enum {
+    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
+    GET_TOKEN,
+    CREATE_SURFACE,
+    DESTROY_SURFACE,
+    SET_STATE
+};
+
+class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
+{
+public:
+    BpSurfaceComposerClient(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceComposerClient>(impl)
+    {
+    }
+
+    virtual sp<IMemoryHeap> getControlBlock() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        remote()->transact(GET_CBLK, data, &reply);
+        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
+    }
+
+    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeStrongBinder(sur->asBinder());
+        remote()->transact(GET_TOKEN, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual sp<ISurface> createSurface( surface_data_t* params,
+                                        int pid,
+                                        const String8& name,
+                                        DisplayID display,
+                                        uint32_t w,
+                                        uint32_t h,
+                                        PixelFormat format,
+                                        uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeInt32(pid);
+        data.writeString8(name);
+        data.writeInt32(display);
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        data.writeInt32(flags);
+        remote()->transact(CREATE_SURFACE, data, &reply);
+        params->readFromParcel(reply);
+        return interface_cast<ISurface>(reply.readStrongBinder());
+    }
+
+    virtual status_t destroySurface(SurfaceID sid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeInt32(sid);
+        remote()->transact(DESTROY_SURFACE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setState(int32_t count, const layer_state_t* states)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeInt32(count);
+        for (int i=0 ; i<count ; i++)
+            states[i].write(data);
+        remote()->transact(SET_STATE, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
+
+// ----------------------------------------------------------------------
+
+status_t BnSurfaceComposerClient::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // codes that don't require permission check
+
+    switch(code) {
+        case GET_CBLK: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            sp<IMemoryHeap> ctl(getControlBlock());
+            reply->writeStrongBinder(ctl->asBinder());
+            return NO_ERROR;
+        } break;
+        case GET_TOKEN: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            sp<ISurface> sur = interface_cast<ISurface>(data.readStrongBinder());
+            ssize_t token = getTokenForSurface(sur);
+            reply->writeInt32(token);
+            return NO_ERROR;
+        } break;
+    }
+
+    // these must be checked
+
+     IPCThreadState* ipc = IPCThreadState::self();
+     const int pid = ipc->getCallingPid();
+     const int uid = ipc->getCallingUid();
+     const int self_pid = getpid();
+     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
+         // we're called from a different process, do the real check
+         if (!checkCallingPermission(
+                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
+         {
+             LOGE("Permission Denial: "
+                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
+             return PERMISSION_DENIED;
+         }
+     }
+
+     switch(code) {
+        case CREATE_SURFACE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            surface_data_t params;
+            int32_t pid = data.readInt32();
+            String8 name = data.readString8();
+            DisplayID display = data.readInt32();
+            uint32_t w = data.readInt32();
+            uint32_t h = data.readInt32();
+            PixelFormat format = data.readInt32();
+            uint32_t flags = data.readInt32();
+            sp<ISurface> s = createSurface(&params, pid, name, display, w, h,
+                    format, flags);
+            params.writeToParcel(reply);
+            reply->writeStrongBinder(s->asBinder());
+            return NO_ERROR;
+        } break;
+        case DESTROY_SURFACE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            reply->writeInt32( destroySurface( data.readInt32() ) );
+            return NO_ERROR;
+        } break;
+        case SET_STATE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            int32_t count = data.readInt32();
+            layer_state_t* states = new layer_state_t[count];
+            for (int i=0 ; i<count ; i++)
+                states[i].read(data);
+            status_t err = setState(count, states);
+            delete [] states;
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------
+
+status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel)
+{
+    token    = parcel.readInt32();
+    identity = parcel.readInt32();
+    width    = parcel.readInt32();
+    height   = parcel.readInt32();
+    format   = parcel.readInt32();
+    return NO_ERROR;
+}
+
+status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const
+{
+    parcel->writeInt32(token);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(width);
+    parcel->writeInt32(height);
+    parcel->writeInt32(format);
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp b/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
deleted file mode 100644
index def96d7..0000000
--- a/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
-#include <private/surfaceflinger/LayerState.h>
-
-// ---------------------------------------------------------------------------
-
-/* ideally AID_GRAPHICS would be in a semi-public header
- * or there would be a way to map a user/group name to its id
- */
-#ifndef AID_GRAPHICS
-#define AID_GRAPHICS 1003
-#endif
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-enum {
-    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_SURFACE,
-    DESTROY_SURFACE,
-    SET_STATE
-};
-
-class BpSurfaceFlingerClient : public BpInterface<ISurfaceFlingerClient>
-{
-public:
-    BpSurfaceFlingerClient(const sp<IBinder>& impl)
-        : BpInterface<ISurfaceFlingerClient>(impl)
-    {
-    }
-
-    virtual sp<IMemoryHeap> getControlBlock() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        remote()->transact(GET_CBLK, data, &reply);
-        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
-    }
-
-    virtual sp<ISurface> createSurface( surface_data_t* params,
-                                        int pid,
-                                        const String8& name,
-                                        DisplayID display,
-                                        uint32_t w,
-                                        uint32_t h,
-                                        PixelFormat format,
-                                        uint32_t flags)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(pid);
-        data.writeString8(name);
-        data.writeInt32(display);
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(format);
-        data.writeInt32(flags);
-        remote()->transact(CREATE_SURFACE, data, &reply);
-        params->readFromParcel(reply);
-        return interface_cast<ISurface>(reply.readStrongBinder());
-    }
-                                    
-    virtual status_t destroySurface(SurfaceID sid)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(sid);
-        remote()->transact(DESTROY_SURFACE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setState(int32_t count, const layer_state_t* states)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(count);
-        for (int i=0 ; i<count ; i++)
-            states[i].write(data);
-        remote()->transact(SET_STATE, data, &reply);
-        return reply.readInt32();
-    }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceFlingerClient::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    // codes that don't require permission check
-
-    switch(code) {
-        case GET_CBLK: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            sp<IMemoryHeap> ctl(getControlBlock());
-            reply->writeStrongBinder(ctl->asBinder());
-            return NO_ERROR;
-        } break;
-    }
-
-    // these must be checked
-     
-     IPCThreadState* ipc = IPCThreadState::self();
-     const int pid = ipc->getCallingPid();
-     const int uid = ipc->getCallingUid();
-     const int self_pid = getpid();
-     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
-         // we're called from a different process, do the real check
-         if (!checkCallingPermission(
-                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
-         {
-             LOGE("Permission Denial: "
-                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
-             return PERMISSION_DENIED;
-         }
-     }
-   
-     switch(code) {
-        case CREATE_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            surface_data_t params;
-            int32_t pid = data.readInt32();
-            String8 name = data.readString8();
-            DisplayID display = data.readInt32();
-            uint32_t w = data.readInt32();
-            uint32_t h = data.readInt32();
-            PixelFormat format = data.readInt32();
-            uint32_t flags = data.readInt32();
-            sp<ISurface> s = createSurface(&params, pid, name, display, w, h,
-                    format, flags);
-            params.writeToParcel(reply);
-            reply->writeStrongBinder(s->asBinder());
-            return NO_ERROR;
-        } break;
-        case DESTROY_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            reply->writeInt32( destroySurface( data.readInt32() ) );
-            return NO_ERROR;
-        } break;
-        case SET_STATE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            int32_t count = data.readInt32();
-            layer_state_t* states = new layer_state_t[count];
-            for (int i=0 ; i<count ; i++)
-                states[i].read(data);
-            status_t err = setState(count, states);
-            delete [] states;
-            reply->writeInt32(err);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------
-
-status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& parcel)
-{
-    token    = parcel.readInt32();
-    identity = parcel.readInt32();
-    width    = parcel.readInt32();
-    height   = parcel.readInt32();
-    format   = parcel.readInt32();
-    return NO_ERROR;
-}
-
-status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
-{
-    parcel->writeInt32(token);
-    parcel->writeInt32(identity);
-    parcel->writeInt32(width);
-    parcel->writeInt32(height);
-    parcel->writeInt32(format);
-    return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index a17e8ac..38b2fae 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -44,15 +44,11 @@
 
 // these functions are used by the clients
 status_t SharedClient::validate(size_t i) const {
-    if (uint32_t(i) >= uint32_t(NUM_LAYERS_MAX))
+    if (uint32_t(i) >= uint32_t(SharedBufferStack::NUM_LAYERS_MAX))
         return BAD_INDEX;
     return surfaces[i].status;
 }
 
-uint32_t SharedClient::getIdentity(size_t token) const {
-    return uint32_t(surfaces[token].identity);
-}
-
 // ----------------------------------------------------------------------------
 
 
@@ -62,24 +58,60 @@
 
 void SharedBufferStack::init(int32_t i)
 {
-    inUse = -1;
+    inUse = -2;
     status = NO_ERROR;
     identity = i;
 }
 
+status_t SharedBufferStack::setCrop(int buffer, const Rect& crop)
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return BAD_INDEX;
+
+    buffers[buffer].crop.l = uint16_t(crop.left);
+    buffers[buffer].crop.t = uint16_t(crop.top);
+    buffers[buffer].crop.r = uint16_t(crop.right);
+    buffers[buffer].crop.b = uint16_t(crop.bottom);
+    return NO_ERROR;
+}
+
+status_t SharedBufferStack::setTransform(int buffer, uint8_t transform)
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return BAD_INDEX;
+    buffers[buffer].transform = transform;
+    return NO_ERROR;
+}
+
 status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
 {
     if (uint32_t(buffer) >= NUM_BUFFER_MAX)
         return BAD_INDEX;
 
-    // in the current implementation we only send a single rectangle
-    const Rect bounds(dirty.getBounds());
-    FlatRegion& reg(dirtyRegion[buffer]);
-    reg.count = 1;
-    reg.rects[0] = uint16_t(bounds.left);
-    reg.rects[1] = uint16_t(bounds.top);
-    reg.rects[2] = uint16_t(bounds.right);
-    reg.rects[3] = uint16_t(bounds.bottom);
+    FlatRegion& reg(buffers[buffer].dirtyRegion);
+    if (dirty.isEmpty()) {
+        reg.count = 0;
+        return NO_ERROR;
+    }
+
+    size_t count;
+    Rect const* r = dirty.getArray(&count);
+    if (count > FlatRegion::NUM_RECT_MAX) {
+        const Rect bounds(dirty.getBounds());
+        reg.count = 1;
+        reg.rects[0].l = uint16_t(bounds.left);
+        reg.rects[0].t = uint16_t(bounds.top);
+        reg.rects[0].r = uint16_t(bounds.right);
+        reg.rects[0].b = uint16_t(bounds.bottom);
+    } else {
+        reg.count = count;
+        for (size_t i=0 ; i<count ; i++) {
+            reg.rects[i].l = uint16_t(r[i].left);
+            reg.rects[i].t = uint16_t(r[i].top);
+            reg.rects[i].r = uint16_t(r[i].right);
+            reg.rects[i].b = uint16_t(r[i].bottom);
+        }
+    }
     return NO_ERROR;
 }
 
@@ -89,18 +121,57 @@
     if (uint32_t(buffer) >= NUM_BUFFER_MAX)
         return res;
 
-    const FlatRegion& reg(dirtyRegion[buffer]);
-    res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3]));
+    const FlatRegion& reg(buffers[buffer].dirtyRegion);
+    if (reg.count > FlatRegion::NUM_RECT_MAX)
+        return res;
+
+    if (reg.count == 1) {
+        const Rect r(
+                reg.rects[0].l,
+                reg.rects[0].t,
+                reg.rects[0].r,
+                reg.rects[0].b);
+        res.set(r);
+    } else {
+        for (size_t i=0 ; i<reg.count ; i++) {
+            const Rect r(
+                    reg.rects[i].l,
+                    reg.rects[i].t,
+                    reg.rects[i].r,
+                    reg.rects[i].b);
+            res.orSelf(r);
+        }
+    }
     return res;
 }
 
+Rect SharedBufferStack::getCrop(int buffer) const
+{
+    Rect res(-1, -1);
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return res;
+    res.left = buffers[buffer].crop.l;
+    res.top = buffers[buffer].crop.t;
+    res.right = buffers[buffer].crop.r;
+    res.bottom = buffers[buffer].crop.b;
+    return res;
+}
+
+uint32_t SharedBufferStack::getTransform(int buffer) const
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return 0;
+    return buffers[buffer].transform;
+}
+
+
 // ----------------------------------------------------------------------------
 
 SharedBufferBase::SharedBufferBase(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
+        int surface, int32_t identity)
     : mSharedClient(sharedClient), 
       mSharedStack(sharedClient->surfaces + surface),
-      mNumBuffers(num), mIdentity(identity)
+      mIdentity(identity)
 {
 }
 
@@ -108,22 +179,16 @@
 {
 }
 
-uint32_t SharedBufferBase::getIdentity()
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.identity;
-}
-
 status_t SharedBufferBase::getStatus() const
 {
     SharedBufferStack& stack( *mSharedStack );
     return stack.status;
 }
 
-size_t SharedBufferBase::getFrontBuffer() const
+int32_t SharedBufferBase::getIdentity() const
 {
     SharedBufferStack& stack( *mSharedStack );
-    return size_t( stack.head );
+    return stack.identity;
 }
 
 String8 SharedBufferBase::dump(char const* prefix) const
@@ -132,16 +197,52 @@
     char buffer[SIZE];
     String8 result;
     SharedBufferStack& stack( *mSharedStack );
-    int tail = (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
     snprintf(buffer, SIZE, 
-            "%s[ head=%2d, available=%2d, queued=%2d, tail=%2d ] "
-            "reallocMask=%08x, inUse=%2d, identity=%d, status=%d\n",
-            prefix, stack.head, stack.available, stack.queued, tail,
+            "%s[ head=%2d, available=%2d, queued=%2d ] "
+            "reallocMask=%08x, inUse=%2d, identity=%d, status=%d",
+            prefix, stack.head, stack.available, stack.queued,
             stack.reallocMask, stack.inUse, stack.identity, stack.status);
     result.append(buffer);
+    result.append("\n");
     return result;
 }
 
+status_t SharedBufferBase::waitForCondition(const ConditionBase& condition)
+{
+    const SharedBufferStack& stack( *mSharedStack );
+    SharedClient& client( *mSharedClient );
+    const nsecs_t TIMEOUT = s2ns(1);
+    const int identity = mIdentity;
+
+    Mutex::Autolock _l(client.lock);
+    while ((condition()==false) &&
+            (stack.identity == identity) &&
+            (stack.status == NO_ERROR))
+    {
+        status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
+        // handle errors and timeouts
+        if (CC_UNLIKELY(err != NO_ERROR)) {
+            if (err == TIMED_OUT) {
+                if (condition()) {
+                    LOGE("waitForCondition(%s) timed out (identity=%d), "
+                        "but condition is true! We recovered but it "
+                        "shouldn't happen." , condition.name(), stack.identity);
+                    break;
+                } else {
+                    LOGW("waitForCondition(%s) timed out "
+                        "(identity=%d, status=%d). "
+                        "CPU may be pegged. trying again.", condition.name(),
+                        stack.identity, stack.status);
+                }
+            } else {
+                LOGE("waitForCondition(%s) error (%s) ",
+                        condition.name(), strerror(-err));
+                return err;
+            }
+        }
+    }
+    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
+}
 // ============================================================================
 // conditions and updates
 // ============================================================================
@@ -149,26 +250,21 @@
 SharedBufferClient::DequeueCondition::DequeueCondition(
         SharedBufferClient* sbc) : ConditionBase(sbc)  { 
 }
-bool SharedBufferClient::DequeueCondition::operator()() {
+bool SharedBufferClient::DequeueCondition::operator()() const {
     return stack.available > 0;
 }
 
 SharedBufferClient::LockCondition::LockCondition(
         SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) { 
 }
-bool SharedBufferClient::LockCondition::operator()() {
-    return (buf != stack.head || 
+bool SharedBufferClient::LockCondition::operator()() const {
+    // NOTE: if stack.head is messed up, we could crash the client
+    // or cause some drawing artifacts. This is okay, as long as it is
+    // limited to the client.
+    return (buf != stack.index[stack.head] ||
             (stack.queued > 0 && stack.inUse != buf));
 }
 
-SharedBufferServer::ReallocateCondition::ReallocateCondition(
-        SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) { 
-}
-bool SharedBufferServer::ReallocateCondition::operator()() {
-    // TODO: we should also check that buf has been dequeued
-    return (buf != stack.head);
-}
-
 // ----------------------------------------------------------------------------
 
 SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
@@ -179,6 +275,16 @@
     return NO_ERROR;
 }
 
+SharedBufferClient::DequeueUpdate::DequeueUpdate(SharedBufferBase* sbb)
+    : UpdateBase(sbb) {
+}
+ssize_t SharedBufferClient::DequeueUpdate::operator()() {
+    if (android_atomic_dec(&stack.available) == 0) {
+        LOGW("dequeue probably called from multiple threads!");
+    }
+    return NO_ERROR;
+}
+
 SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb)
     : UpdateBase(sbb) {    
 }
@@ -193,8 +299,10 @@
 }
 ssize_t SharedBufferServer::UnlockUpdate::operator()() {
     if (stack.inUse != lockedBuffer) {
-        LOGE("unlocking %d, but currently locked buffer is %d",
-                lockedBuffer, stack.inUse);
+        LOGE("unlocking %d, but currently locked buffer is %d "
+             "(identity=%d, token=%d)",
+                lockedBuffer, stack.inUse,
+                stack.identity, stack.token);
         return BAD_VALUE;
     }
     android_atomic_write(-1, &stack.inUse);
@@ -206,11 +314,12 @@
     : UpdateBase(sbb), numBuffers(numBuffers) {
 }
 ssize_t SharedBufferServer::RetireUpdate::operator()() {
-    // head is only written in this function, which is single-thread.
     int32_t head = stack.head;
+    if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
 
     // Preventively lock the current buffer before updating queued.
-    android_atomic_write(head, &stack.inUse);
+    android_atomic_write(stack.index[head], &stack.inUse);
 
     // Decrement the number of queued buffers 
     int32_t queued;
@@ -221,16 +330,15 @@
         }
     } while (android_atomic_cmpxchg(queued, queued-1, &stack.queued));
     
-    // update the head pointer
-    head = ((head+1 >= numBuffers) ? 0 : head+1);
-
     // lock the buffer before advancing head, which automatically unlocks
     // the buffer we preventively locked upon entering this function
-    android_atomic_write(head, &stack.inUse);
 
-    // advance head
+    head = (head + 1) % numBuffers;
+    android_atomic_write(stack.index[head], &stack.inUse);
+
+    // head is only modified here, so we don't need to use cmpxchg
     android_atomic_write(head, &stack.head);
-    
+
     // now that head has moved, we can increment the number of available buffers
     android_atomic_inc(&stack.available);
     return head;
@@ -250,41 +358,31 @@
 
 SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
         int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity), tail(0)
+    : SharedBufferBase(sharedClient, surface, identity),
+      mNumBuffers(num), tail(0), undoDequeueTail(0)
 {
+    SharedBufferStack& stack( *mSharedStack );
     tail = computeTail();
+    queued_head = stack.head;
 }
 
 int32_t SharedBufferClient::computeTail() const
 {
     SharedBufferStack& stack( *mSharedStack );
-    // we need to make sure we read available and head coherently,
-    // w.r.t RetireUpdate.
-    int32_t newTail;
-    int32_t avail;
-    int32_t head;
-    do {
-        avail = stack.available;
-        head = stack.head;
-    } while (stack.available != avail);
-    newTail = head - avail + 1;
-    if (newTail < 0) {
-        newTail += mNumBuffers;
-    } else if (newTail >= mNumBuffers) {
-        newTail -= mNumBuffers;
-    }
-    return newTail;
+    return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
 }
 
 ssize_t SharedBufferClient::dequeue()
 {
     SharedBufferStack& stack( *mSharedStack );
 
-    if (stack.head == tail && stack.available == 2) {
+    if (stack.head == tail && stack.available == mNumBuffers) {
         LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
                 tail, stack.head, stack.available, stack.queued);
     }
-        
+
+    RWLock::AutoRLock _rd(mLock);
+
     const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
 
     //LOGD("[%d] about to dequeue a buffer",
@@ -294,16 +392,13 @@
     if (err != NO_ERROR)
         return ssize_t(err);
 
-    // NOTE: 'stack.available' is part of the conditions, however
-    // decrementing it, never changes any conditions, so we don't need
-    // to do this as part of an update.
-    if (android_atomic_dec(&stack.available) == 0) {
-        LOGW("dequeue probably called from multiple threads!");
-    }
+    DequeueUpdate update(this);
+    updateCondition( update );
 
-    int dequeued = tail;
+    undoDequeueTail = tail;
+    int dequeued = stack.index[tail];
     tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
-    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
+    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail++=%d, %s",
             dequeued, tail, dump("").string());
 
     mDequeueTime[dequeued] = dequeueTime; 
@@ -313,16 +408,23 @@
 
 status_t SharedBufferClient::undoDequeue(int buf)
 {
+    RWLock::AutoRLock _rd(mLock);
+
+    // TODO: we can only undo the previous dequeue, we should
+    // enforce that in the api
     UndoDequeueUpdate update(this);
     status_t err = updateCondition( update );
     if (err == NO_ERROR) {
-        tail = computeTail();
+        tail = undoDequeueTail;
     }
     return err;
 }
 
 status_t SharedBufferClient::lock(int buf)
 {
+    RWLock::AutoRLock _rd(mLock);
+
+    SharedBufferStack& stack( *mSharedStack );
     LockCondition condition(this, buf);
     status_t err = waitForCondition(condition);
     return err;
@@ -330,53 +432,111 @@
 
 status_t SharedBufferClient::queue(int buf)
 {
+    RWLock::AutoRLock _rd(mLock);
+
+    SharedBufferStack& stack( *mSharedStack );
+
+    queued_head = (queued_head + 1) % mNumBuffers;
+    stack.index[queued_head] = buf;
+
     QueueUpdate update(this);
     status_t err = updateCondition( update );
     LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
-    SharedBufferStack& stack( *mSharedStack );
+
     const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
     stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
     return err;
 }
 
-bool SharedBufferClient::needNewBuffer(int buffer) const
+bool SharedBufferClient::needNewBuffer(int buf) const
 {
     SharedBufferStack& stack( *mSharedStack );
-    const uint32_t mask = 1<<buffer;
+    const uint32_t mask = 1<<(31-buf);
     return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
 }
 
-status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
+status_t SharedBufferClient::setCrop(int buf, const Rect& crop)
 {
     SharedBufferStack& stack( *mSharedStack );
-    return stack.setDirtyRegion(buffer, reg);
+    return stack.setCrop(buf, crop);
+}
+
+status_t SharedBufferClient::setTransform(int buf, uint32_t transform)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.setTransform(buf, uint8_t(transform));
+}
+
+status_t SharedBufferClient::setDirtyRegion(int buf, const Region& reg)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.setDirtyRegion(buf, reg);
+}
+
+status_t SharedBufferClient::setBufferCount(
+        int bufferCount, const SetBufferCountCallback& ipc)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    if (uint32_t(bufferCount) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
+
+    if (uint32_t(bufferCount) < SharedBufferStack::NUM_BUFFER_MIN)
+        return BAD_VALUE;
+
+    RWLock::AutoWLock _wr(mLock);
+
+    status_t err = ipc(bufferCount);
+    if (err == NO_ERROR) {
+        mNumBuffers = bufferCount;
+        queued_head = (stack.head + stack.queued) % mNumBuffers;
+    }
+    return err;
 }
 
 // ----------------------------------------------------------------------------
 
 SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
         int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity)
+    : SharedBufferBase(sharedClient, surface, identity),
+      mNumBuffers(num)
 {
     mSharedStack->init(identity);
+    mSharedStack->token = surface;
     mSharedStack->head = num-1;
     mSharedStack->available = num;
     mSharedStack->queued = 0;
     mSharedStack->reallocMask = 0;
-    memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion));
+    memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers));
+    for (int i=0 ; i<num ; i++) {
+        mBufferList.add(i);
+        mSharedStack->index[i] = i;
+    }
+}
+
+SharedBufferServer::~SharedBufferServer()
+{
 }
 
 ssize_t SharedBufferServer::retireAndLock()
 {
+    RWLock::AutoRLock _l(mLock);
+
     RetireUpdate update(this, mNumBuffers);
     ssize_t buf = updateCondition( update );
-    LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s", int(buf), dump("").string());
+    if (buf >= 0) {
+        if (uint32_t(buf) >= SharedBufferStack::NUM_BUFFER_MAX)
+            return BAD_VALUE;
+        SharedBufferStack& stack( *mSharedStack );
+        buf = stack.index[buf];
+        LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s",
+                int(buf), dump("").string());
+    }
     return buf;
 }
 
-status_t SharedBufferServer::unlock(int buffer)
+status_t SharedBufferServer::unlock(int buf)
 {
-    UnlockUpdate update(this, buffer);
+    UnlockUpdate update(this, buf);
     status_t err = updateCondition( update );
     return err;
 }
@@ -389,11 +549,25 @@
     }
 }
 
-status_t SharedBufferServer::reallocate()
+status_t SharedBufferServer::reallocateAll()
 {
+    RWLock::AutoRLock _l(mLock);
+
     SharedBufferStack& stack( *mSharedStack );
-    uint32_t mask = (1<<mNumBuffers)-1;
-    android_atomic_or(mask, &stack.reallocMask); 
+    uint32_t mask = mBufferList.getMask();
+    android_atomic_or(mask, &stack.reallocMask);
+    return NO_ERROR;
+}
+
+status_t SharedBufferServer::reallocateAllExcept(int buffer)
+{
+    RWLock::AutoRLock _l(mLock);
+
+    SharedBufferStack& stack( *mSharedStack );
+    BufferList temp(mBufferList);
+    temp.remove(buffer);
+    uint32_t mask = temp.getMask();
+    android_atomic_or(mask, &stack.reallocMask);
     return NO_ERROR;
 }
 
@@ -403,17 +577,74 @@
     return stack.queued;
 }
 
-status_t SharedBufferServer::assertReallocate(int buffer)
-{
-    ReallocateCondition condition(this, buffer);
-    status_t err = waitForCondition(condition);
-    return err;
-}
-
-Region SharedBufferServer::getDirtyRegion(int buffer) const
+Region SharedBufferServer::getDirtyRegion(int buf) const
 {
     SharedBufferStack& stack( *mSharedStack );
-    return stack.getDirtyRegion(buffer);
+    return stack.getDirtyRegion(buf);
+}
+
+Rect SharedBufferServer::getCrop(int buf) const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.getCrop(buf);
+}
+
+uint32_t SharedBufferServer::getTransform(int buf) const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.getTransform(buf);
+}
+
+/*
+ * NOTE: this is not thread-safe on the server-side, meaning
+ * 'head' cannot move during this operation. The client-side
+ * can safely operate an usual.
+ *
+ */
+status_t SharedBufferServer::resize(int newNumBuffers)
+{
+    if (uint32_t(newNumBuffers) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
+
+    RWLock::AutoWLock _l(mLock);
+
+    // for now we're not supporting shrinking
+    const int numBuffers = mNumBuffers;
+    if (newNumBuffers < numBuffers)
+        return BAD_VALUE;
+
+    SharedBufferStack& stack( *mSharedStack );
+    const int extra = newNumBuffers - numBuffers;
+
+    // read the head, make sure it's valid
+    int32_t head = stack.head;
+    if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
+
+    int base = numBuffers;
+    int32_t avail = stack.available;
+    int tail = head - avail + 1;
+
+    if (tail >= 0) {
+        int8_t* const index = const_cast<int8_t*>(stack.index);
+        const int nb = numBuffers - head;
+        memmove(&index[head + extra], &index[head], nb);
+        base = head;
+        // move head 'extra' ahead, this doesn't impact stack.index[head];
+        stack.head = head + extra;
+    }
+    stack.available += extra;
+
+    // fill the new free space with unused buffers
+    BufferList::const_iterator curr(mBufferList.free_begin());
+    for (int i=0 ; i<extra ; i++) {
+        stack.index[base+i] = *curr;
+        mBufferList.add(*curr);
+        ++curr;
+    }
+
+    mNumBuffers = newNumBuffers;
+    return NO_ERROR;
 }
 
 SharedBufferStack::Statistics SharedBufferServer::getStats() const
@@ -422,6 +653,29 @@
     return stack.stats;
 }
 
+// ---------------------------------------------------------------------------
+status_t SharedBufferServer::BufferList::add(int value)
+{
+    if (uint32_t(value) >= mCapacity)
+        return BAD_VALUE;
+    uint32_t mask = 1<<(31-value);
+    if (mList & mask)
+        return ALREADY_EXISTS;
+    mList |= mask;
+    return NO_ERROR;
+}
+
+status_t SharedBufferServer::BufferList::remove(int value)
+{
+    if (uint32_t(value) >= mCapacity)
+        return BAD_VALUE;
+    uint32_t mask = 1<<(31-value);
+    if (!(mList & mask))
+        return NAME_NOT_FOUND;
+    mList &= ~mask;
+    return NO_ERROR;
+}
+
 
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 5dd75c3..cb76091 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -17,8 +17,6 @@
 #define LOG_TAG "Surface"
 
 #include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -28,8 +26,6 @@
 #include <utils/CallStack.h>
 #include <utils/Log.h>
 
-#include <pixelflinger/pixelflinger.h>
-
 #include <binder/IPCThreadState.h>
 #include <binder/IMemory.h>
 
@@ -55,6 +51,8 @@
         const sp<GraphicBuffer>& src, 
         const Region& reg)
 {
+    // src and dst with, height and format must be identical. no verification
+    // is done here.
     status_t err;
     uint8_t const * src_bits = NULL;
     err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
@@ -67,7 +65,6 @@
     Region::const_iterator head(reg.begin());
     Region::const_iterator tail(reg.end());
     if (head != tail && src_bits && dst_bits) {
-        // NOTE: dst and src must be the same format
         const size_t bpp = bytesPerPixel(src->format);
         const size_t dbpr = dst->stride * bpp;
         const size_t sbpr = src->stride * bpp;
@@ -107,7 +104,7 @@
 SurfaceControl::SurfaceControl(
         const sp<SurfaceComposerClient>& client, 
         const sp<ISurface>& surface,
-        const ISurfaceFlingerClient::surface_data_t& data,
+        const ISurfaceComposerClient::surface_data_t& data,
         uint32_t w, uint32_t h, PixelFormat format, uint32_t flags)
     : mClient(client), mSurface(surface),
       mToken(data.token), mIdentity(data.identity),
@@ -154,75 +151,75 @@
 }
 
 status_t SurfaceControl::setLayer(int32_t layer) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setLayer(mToken, layer);
 }
 status_t SurfaceControl::setPosition(int32_t x, int32_t y) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setPosition(mToken, x, y);
 }
 status_t SurfaceControl::setSize(uint32_t w, uint32_t h) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setSize(mToken, w, h);
 }
 status_t SurfaceControl::hide() {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->hide(mToken);
 }
 status_t SurfaceControl::show(int32_t layer) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->show(mToken, layer);
 }
 status_t SurfaceControl::freeze() {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->freeze(mToken);
 }
 status_t SurfaceControl::unfreeze() {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->unfreeze(mToken);
 }
 status_t SurfaceControl::setFlags(uint32_t flags, uint32_t mask) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setFlags(mToken, flags, mask);
 }
 status_t SurfaceControl::setTransparentRegionHint(const Region& transparent) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setTransparentRegionHint(mToken, transparent);
 }
 status_t SurfaceControl::setAlpha(float alpha) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setAlpha(mToken, alpha);
 }
 status_t SurfaceControl::setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setMatrix(mToken, dsdx, dtdx, dsdy, dtdy);
 }
 status_t SurfaceControl::setFreezeTint(uint32_t tint) {
-    const sp<SurfaceComposerClient>& client(mClient);
     status_t err = validate();
     if (err < 0) return err;
+    const sp<SurfaceComposerClient>& client(mClient);
     return client->setFreezeTint(mToken, tint);
 }
 
@@ -233,50 +230,27 @@
                 mToken, mIdentity, mClient.get());
         return NO_INIT;
     }
-    SharedClient const* cblk = mClient->mControl;
-    if (cblk == 0) {
-        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
-        return NO_INIT;
-    }
-    status_t err = cblk->validate(mToken);
-    if (err != NO_ERROR) {
-        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
-                mToken, mIdentity, err, strerror(-err));
-        return err;
-    }
-    uint32_t identity = cblk->getIdentity(mToken);
-    if (mIdentity != identity) {
-        LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, identity);
-        return NO_INIT;
-    }
     return NO_ERROR;
 }
 
 status_t SurfaceControl::writeSurfaceToParcel(
         const sp<SurfaceControl>& control, Parcel* parcel)
 {
-    uint32_t flags = 0;
-    uint32_t format = 0;
-    SurfaceID token = -1;
+    sp<ISurface> sur;
     uint32_t identity = 0;
     uint32_t width = 0;
     uint32_t height = 0;
-    sp<SurfaceComposerClient> client;
-    sp<ISurface> sur;
+    uint32_t format = 0;
+    uint32_t flags = 0;
     if (SurfaceControl::isValid(control)) {
-        token    = control->mToken;
-        identity = control->mIdentity;
-        client   = control->mClient;
         sur      = control->mSurface;
+        identity = control->mIdentity;
         width    = control->mWidth;
         height   = control->mHeight;
         format   = control->mFormat;
         flags    = control->mFlags;
     }
-    parcel->writeStrongBinder(client!=0  ? client->connection() : NULL);
-    parcel->writeStrongBinder(sur!=0     ? sur->asBinder()      : NULL);
-    parcel->writeInt32(token);
+    parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
     parcel->writeInt32(identity);
     parcel->writeInt32(width);
     parcel->writeInt32(height);
@@ -298,70 +272,180 @@
 //  Surface
 // ============================================================================
 
+class SurfaceClient : public Singleton<SurfaceClient>
+{
+    // all these attributes are constants
+    sp<ISurfaceComposer> mComposerService;
+    sp<ISurfaceComposerClient> mClient;
+    status_t mStatus;
+    SharedClient* mControl;
+    sp<IMemoryHeap> mControlMemory;
+
+    SurfaceClient()
+        : Singleton<SurfaceClient>(), mStatus(NO_INIT)
+    {
+        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+        mComposerService = sf;
+        mClient = sf->createClientConnection();
+        if (mClient != NULL) {
+            mControlMemory = mClient->getControlBlock();
+            if (mControlMemory != NULL) {
+                mControl = static_cast<SharedClient *>(
+                        mControlMemory->getBase());
+                if (mControl) {
+                    mStatus = NO_ERROR;
+                }
+            }
+        }
+    }
+    friend class Singleton<SurfaceClient>;
+public:
+    status_t initCheck() const {
+        return mStatus;
+    }
+    SharedClient* getSharedClient() const {
+        return mControl;
+    }
+    ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
+        // TODO: we could cache a few tokens here to avoid an IPC
+        return mClient->getTokenForSurface(sur);
+    }
+    void signalServer() const {
+        mComposerService->signal();
+    }
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
+
+// ---------------------------------------------------------------------------
+
 Surface::Surface(const sp<SurfaceControl>& surface)
-    : mClient(surface->mClient), mSurface(surface->mSurface),
-      mToken(surface->mToken), mIdentity(surface->mIdentity),
+    : mBufferMapper(GraphicBufferMapper::get()),
+      mClient(SurfaceClient::getInstance()),
+      mSharedBufferClient(NULL),
+      mInitCheck(NO_INIT),
+      mSurface(surface->mSurface),
+      mIdentity(surface->mIdentity),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
-      mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL),
       mWidth(surface->mWidth), mHeight(surface->mHeight)
 {
-    mSharedBufferClient = new SharedBufferClient(
-            mClient->mControl, mToken, 2, mIdentity);
-
     init();
 }
 
-Surface::Surface(const Parcel& parcel)
-    :  mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL)
+Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
+    : mBufferMapper(GraphicBufferMapper::get()),
+      mClient(SurfaceClient::getInstance()),
+      mSharedBufferClient(NULL),
+      mInitCheck(NO_INIT)
 {
-    sp<IBinder> clientBinder = parcel.readStrongBinder();
-    mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
-    mToken      = parcel.readInt32();
+    mSurface    = interface_cast<ISurface>(ref);
     mIdentity   = parcel.readInt32();
     mWidth      = parcel.readInt32();
     mHeight     = parcel.readInt32();
     mFormat     = parcel.readInt32();
     mFlags      = parcel.readInt32();
-
-    // FIXME: what does that mean if clientBinder is NULL here?
-    if (clientBinder != NULL) {
-        mClient = SurfaceComposerClient::clientForConnection(clientBinder);
-
-        mSharedBufferClient = new SharedBufferClient(
-                mClient->mControl, mToken, 2, mIdentity);
-    }
-
     init();
 }
 
+status_t Surface::writeToParcel(
+        const sp<Surface>& surface, Parcel* parcel)
+{
+    sp<ISurface> sur;
+    uint32_t identity = 0;
+    uint32_t width = 0;
+    uint32_t height = 0;
+    uint32_t format = 0;
+    uint32_t flags = 0;
+    if (Surface::isValid(surface)) {
+        sur      = surface->mSurface;
+        identity = surface->mIdentity;
+        width    = surface->mWidth;
+        height   = surface->mHeight;
+        format   = surface->mFormat;
+        flags    = surface->mFlags;
+    }
+    parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(width);
+    parcel->writeInt32(height);
+    parcel->writeInt32(format);
+    parcel->writeInt32(flags);
+    return NO_ERROR;
+
+}
+
+
+Mutex Surface::sCachedSurfacesLock;
+DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
+
+sp<Surface> Surface::readFromParcel(const Parcel& data) {
+    Mutex::Autolock _l(sCachedSurfacesLock);
+    sp<IBinder> binder(data.readStrongBinder());
+    sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
+    if (surface == 0) {
+       surface = new Surface(data, binder);
+       sCachedSurfaces.add(binder, surface);
+    }
+    if (surface->mSurface == 0) {
+      surface = 0;
+    }
+    cleanCachedSurfaces();
+    return surface;
+}
+
+// Remove the stale entries from the surface cache.  This should only be called
+// with sCachedSurfacesLock held.
+void Surface::cleanCachedSurfaces() {
+    for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
+        wp<Surface> s(sCachedSurfaces.valueAt(i));
+        if (s == 0 || s.promote() == 0) {
+            sCachedSurfaces.removeItemsAt(i);
+        }
+    }
+}
+
 void Surface::init()
 {
-    android_native_window_t::setSwapInterval  = setSwapInterval;
-    android_native_window_t::dequeueBuffer    = dequeueBuffer;
-    android_native_window_t::lockBuffer       = lockBuffer;
-    android_native_window_t::queueBuffer      = queueBuffer;
-    android_native_window_t::query            = query;
-    android_native_window_t::perform          = perform;
-    mSwapRectangle.makeInvalid();
+    ANativeWindow::setSwapInterval  = setSwapInterval;
+    ANativeWindow::dequeueBuffer    = dequeueBuffer;
+    ANativeWindow::lockBuffer       = lockBuffer;
+    ANativeWindow::queueBuffer      = queueBuffer;
+    ANativeWindow::query            = query;
+    ANativeWindow::perform          = perform;
+
     DisplayInfo dinfo;
     SurfaceComposerClient::getDisplayInfo(0, &dinfo);
-    const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
-    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
+    const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
+    const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
     // FIXME: set real values here
-    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
-    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
-    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
-    // be default we request a hardware surface
-    mUsage = GRALLOC_USAGE_HW_RENDER;
+    const_cast<int&>(ANativeWindow::minSwapInterval) = 1;
+    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
+    const_cast<uint32_t&>(ANativeWindow::flags) = 0;
+
+    mNextBufferTransform = 0;
     mConnected = 0;
-    mNeedFullUpdate = false;
+    mSwapRectangle.makeInvalid();
+    mNextBufferCrop = Rect(0,0);
+    // two buffers by default
+    mBuffers.setCapacity(2);
+    mBuffers.insertAt(0, 2);
+
+    if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
+        int32_t token = mClient.getTokenForSurface(mSurface);
+        if (token >= 0) {
+            mSharedBufferClient = new SharedBufferClient(
+                    mClient.getSharedClient(), token, 2, mIdentity);
+            mInitCheck = mClient.getSharedClient()->validate(token);
+        }
+    }
 }
 
 Surface::~Surface()
 {
     // this is a client-side operation, the surface is destroyed, unmap
     // its buffers in this process.
-    for (int i=0 ; i<2 ; i++) {
+    size_t size = mBuffers.size();
+    for (size_t i=0 ; i<size ; i++) {
         if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
             getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
         }
@@ -369,93 +453,88 @@
 
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
-    mClient.clear();
+    mBuffers.clear();
     mSurface.clear();
     delete mSharedBufferClient;
     IPCThreadState::self()->flushCommands();
 }
 
-sp<SurfaceComposerClient> Surface::getClient() const {
-    return mClient;
+bool Surface::isValid() {
+    return mInitCheck == NO_ERROR;
+}
+
+status_t Surface::validate() const
+{
+    // check that we initialized ourself properly
+    if (mInitCheck != NO_ERROR) {
+        LOGE("invalid token (identity=%u)", mIdentity);
+        return mInitCheck;
+    }
+
+    // verify the identity of this surface
+    uint32_t identity = mSharedBufferClient->getIdentity();
+
+    // this is a bit of a (temporary) special case, identity==0 means that
+    // no operation are allowed from the client (eg: dequeue/queue), this
+    // is used with PUSH_BUFFER surfaces for instance
+    if (identity == 0) {
+        LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
+        return INVALID_OPERATION;
+    }
+
+    if (mIdentity != identity) {
+        LOGE("[Surface] using an invalid surface, "
+                "identity=%u should be %d",
+                mIdentity, identity);
+        return NO_INIT;
+    }
+
+    // check the surface didn't become invalid
+    status_t err = mSharedBufferClient->getStatus();
+    if (err != NO_ERROR) {
+        LOGE("surface (identity=%u) is invalid, err=%d (%s)",
+                mIdentity, err, strerror(-err));
+        return err;
+    }
+
+    return NO_ERROR;
 }
 
 sp<ISurface> Surface::getISurface() const {
     return mSurface;
 }
 
-bool Surface::isValid() {
-    return mToken>=0 && mClient!=0;
-}
-
-status_t Surface::validate() const
-{
-    sp<SurfaceComposerClient> client(getClient());
-    if (mToken<0 || mClient==0) {
-        LOGE("invalid token (%d, identity=%u) or client (%p)", 
-                mToken, mIdentity, client.get());
-        return NO_INIT;
-    }
-    SharedClient const* cblk = mClient->mControl;
-    if (cblk == 0) {
-        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
-        return NO_INIT;
-    }
-    status_t err = cblk->validate(mToken);
-    if (err != NO_ERROR) {
-        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
-                mToken, mIdentity, err, strerror(-err));
-        return err;
-    }
-    uint32_t identity = cblk->getIdentity(mToken);
-    if (mIdentity != identity) {
-        LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, identity);
-        return NO_INIT;
-    }
-    return NO_ERROR;
-}
-
-
-bool Surface::isSameSurface(
-        const sp<Surface>& lhs, const sp<Surface>& rhs) 
-{
-    if (lhs == 0 || rhs == 0)
-        return false;
-
-    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
-}
-
 // ----------------------------------------------------------------------------
 
-int Surface::setSwapInterval(android_native_window_t* window, int interval) {
+int Surface::setSwapInterval(ANativeWindow* window, int interval) {
     return 0;
 }
 
-int Surface::dequeueBuffer(android_native_window_t* window, 
+int Surface::dequeueBuffer(ANativeWindow* window, 
         android_native_buffer_t** buffer) {
     Surface* self = getSelf(window);
     return self->dequeueBuffer(buffer);
 }
 
-int Surface::lockBuffer(android_native_window_t* window, 
+int Surface::lockBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer) {
     Surface* self = getSelf(window);
     return self->lockBuffer(buffer);
 }
 
-int Surface::queueBuffer(android_native_window_t* window, 
+int Surface::queueBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer) {
     Surface* self = getSelf(window);
     return self->queueBuffer(buffer);
 }
 
-int Surface::query(android_native_window_t* window, 
+int Surface::query(ANativeWindow* window, 
         int what, int* value) {
     Surface* self = getSelf(window);
     return self->query(what, value);
 }
 
-int Surface::perform(android_native_window_t* window, 
+int Surface::perform(ANativeWindow* window, 
         int operation, ...) {
     va_list args;
     va_start(args, operation);
@@ -467,21 +546,24 @@
 
 // ----------------------------------------------------------------------------
 
-status_t Surface::dequeueBuffer(sp<GraphicBuffer>* buffer) {
-    android_native_buffer_t* out;
-    status_t err = dequeueBuffer(&out);
-    if (err == NO_ERROR) {
-        *buffer = GraphicBuffer::getSelf(out);
+bool Surface::needNewBuffer(int bufIdx,
+        uint32_t *pWidth, uint32_t *pHeight,
+        uint32_t *pFormat, uint32_t *pUsage) const
+{
+    Mutex::Autolock _l(mSurfaceLock);
+
+    // Always call needNewBuffer(), since it clears the needed buffers flags
+    bool needNewBuffer = mSharedBufferClient->needNewBuffer(bufIdx);
+    bool validBuffer = mBufferInfo.validateBuffer(mBuffers[bufIdx]);
+    bool newNeewBuffer = needNewBuffer || !validBuffer;
+    if (newNeewBuffer) {
+        mBufferInfo.get(pWidth, pHeight, pFormat, pUsage);
     }
-    return err;
+    return newNeewBuffer;
 }
 
-// ----------------------------------------------------------------------------
-
-
 int Surface::dequeueBuffer(android_native_buffer_t** buffer)
 {
-    sp<SurfaceComposerClient> client(getClient());
     status_t err = validate();
     if (err != NO_ERROR)
         return err;
@@ -492,24 +574,28 @@
         return bufIdx;
     }
 
-    // below we make sure we AT LEAST have the usage flags we want
-    const uint32_t usage(getUsage());
-    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
-    if (backBuffer == 0 || 
-        ((uint32_t(backBuffer->usage) & usage) != usage) ||
-        mSharedBufferClient->needNewBuffer(bufIdx)) 
-    {
-        err = getBufferLocked(bufIdx, usage);
-        LOGE_IF(err, "getBufferLocked(%ld, %08x) failed (%s)",
-                bufIdx, usage, strerror(-err));
+    // grow the buffer array if needed
+    const size_t size = mBuffers.size();
+    const size_t needed = bufIdx+1;
+    if (size < needed) {
+        mBuffers.insertAt(size, needed-size);
+    }
+
+    uint32_t w, h, format, usage;
+    if (needNewBuffer(bufIdx, &w, &h, &format, &usage)) {
+        err = getBufferLocked(bufIdx, w, h, format, usage);
+        LOGE_IF(err, "getBufferLocked(%ld, %u, %u, %u, %08x) failed (%s)",
+                bufIdx, w, h, format, usage, strerror(-err));
         if (err == NO_ERROR) {
             // reset the width/height with the what we get from the buffer
+            const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
             mWidth  = uint32_t(backBuffer->width);
             mHeight = uint32_t(backBuffer->height);
         }
     }
 
     // if we still don't have a buffer here, we probably ran out of memory
+    const sp<GraphicBuffer>& backBuffer(mBuffers[bufIdx]);
     if (!err && backBuffer==0) {
         err = NO_MEMORY;
     }
@@ -526,12 +612,11 @@
 
 int Surface::lockBuffer(android_native_buffer_t* buffer)
 {
-    sp<SurfaceComposerClient> client(getClient());
     status_t err = validate();
     if (err != NO_ERROR)
         return err;
 
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
     err = mSharedBufferClient->lock(bufIdx);
     LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
     return err;
@@ -539,7 +624,6 @@
 
 int Surface::queueBuffer(android_native_buffer_t* buffer)
 {   
-    sp<SurfaceComposerClient> client(getClient());
     status_t err = validate();
     if (err != NO_ERROR)
         return err;
@@ -548,14 +632,16 @@
         mDirtyRegion.set(mSwapRectangle);
     }
     
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
+    mSharedBufferClient->setTransform(bufIdx, mNextBufferTransform);
+    mSharedBufferClient->setCrop(bufIdx, mNextBufferCrop);
     mSharedBufferClient->setDirtyRegion(bufIdx, mDirtyRegion);
     err = mSharedBufferClient->queue(bufIdx);
     LOGE_IF(err, "error queuing buffer %d (%s)", bufIdx, strerror(-err));
 
     if (err == NO_ERROR) {
-        // FIXME: can we avoid this IPC if we know there is one pending?
-        client->signalServer();
+        // TODO: can we avoid this IPC if we know there is one pending?
+        mClient.signalServer();
     }
     return err;
 }
@@ -578,6 +664,10 @@
 
 int Surface::perform(int operation, va_list args)
 {
+    status_t err = validate();
+    if (err != NO_ERROR)
+        return err;
+
     int res = NO_ERROR;
     switch (operation) {
     case NATIVE_WINDOW_SET_USAGE:
@@ -589,6 +679,18 @@
     case NATIVE_WINDOW_DISCONNECT:
         res = dispatch_disconnect( args );
         break;
+    case NATIVE_WINDOW_SET_CROP:
+        res = dispatch_crop( args );
+        break;
+    case NATIVE_WINDOW_SET_BUFFER_COUNT:
+        res = dispatch_set_buffer_count( args );
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_GEOMETRY:
+        res = dispatch_set_buffers_geometry( args );
+        break;
+    case NATIVE_WINDOW_SET_BUFFERS_TRANSFORM:
+        res = dispatch_set_buffers_transform( args );
+        break;
     default:
         res = NAME_NOT_FOUND;
         break;
@@ -608,12 +710,30 @@
     int api = va_arg(args, int);
     return disconnect( api );
 }
+int Surface::dispatch_crop(va_list args) {
+    android_native_rect_t const* rect = va_arg(args, android_native_rect_t*);
+    return crop( reinterpret_cast<Rect const*>(rect) );
+}
+int Surface::dispatch_set_buffer_count(va_list args) {
+    size_t bufferCount = va_arg(args, size_t);
+    return setBufferCount(bufferCount);
+}
+int Surface::dispatch_set_buffers_geometry(va_list args) {
+    int w = va_arg(args, int);
+    int h = va_arg(args, int);
+    int f = va_arg(args, int);
+    return setBuffersGeometry(w, h, f);
+}
 
+int Surface::dispatch_set_buffers_transform(va_list args) {
+    int transform = va_arg(args, int);
+    return setBuffersTransform(transform);
+}
 
 void Surface::setUsage(uint32_t reqUsage)
 {
     Mutex::Autolock _l(mSurfaceLock);
-    mUsage = reqUsage;
+    mBufferInfo.set(reqUsage);
 }
 
 int Surface::connect(int api)
@@ -654,19 +774,66 @@
     return err;
 }
 
-uint32_t Surface::getUsage() const
+int Surface::crop(Rect const* rect)
+{
+    // empty/invalid rects are not allowed
+    if (rect->isEmpty())
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mSurfaceLock);
+    // TODO: validate rect size
+    mNextBufferCrop = *rect;
+    return NO_ERROR;
+}
+
+int Surface::setBufferCount(int bufferCount)
+{
+    sp<ISurface> s(mSurface);
+    if (s == 0) return NO_INIT;
+
+    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
+        sp<ISurface> surface;
+        virtual status_t operator()(int bufferCount) const {
+            return surface->setBufferCount(bufferCount);
+        }
+    public:
+        SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
+    } ipc(s);
+
+    status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
+    LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
+            bufferCount, strerror(-err));
+    return err;
+}
+
+int Surface::setBuffersGeometry(int w, int h, int format)
+{
+    if (w<0 || h<0 || format<0)
+        return BAD_VALUE;
+
+    if ((w && !h) || (!w && h))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mSurfaceLock);
+    mBufferInfo.set(w, h, format);
+    return NO_ERROR;
+}
+
+int Surface::setBuffersTransform(int transform)
 {
     Mutex::Autolock _l(mSurfaceLock);
-    return mUsage;
+    mNextBufferTransform = transform;
+    return NO_ERROR;
 }
 
+// ----------------------------------------------------------------------------
+
 int Surface::getConnectedApi() const
 {
     Mutex::Autolock _l(mSurfaceLock);
     return mConnected;
 }
 
-
 // ----------------------------------------------------------------------------
 
 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -677,7 +844,7 @@
 {
     if (getConnectedApi()) {
         LOGE("Surface::lock(%p) failed. Already connected to another API",
-                (android_native_window_t*)this);
+                (ANativeWindow*)this);
         CallStack stack;
         stack.update();
         stack.dump("");
@@ -703,45 +870,47 @@
     // we're intending to do software rendering from this point
     setUsage(GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN);
 
-    sp<GraphicBuffer> backBuffer;
-    status_t err = dequeueBuffer(&backBuffer);
+    android_native_buffer_t* out;
+    status_t err = dequeueBuffer(&out);
     LOGE_IF(err, "dequeueBuffer failed (%s)", strerror(-err));
     if (err == NO_ERROR) {
+        sp<GraphicBuffer> backBuffer(GraphicBuffer::getSelf(out));
         err = lockBuffer(backBuffer.get());
         LOGE_IF(err, "lockBuffer (idx=%d) failed (%s)",
-                backBuffer->getIndex(), strerror(-err));
+                getBufferIndex(backBuffer), strerror(-err));
         if (err == NO_ERROR) {
-            // we handle copy-back here...
-
             const Rect bounds(backBuffer->width, backBuffer->height);
-            Region scratch(bounds);
+            const Region boundsRegion(bounds);
+            Region scratch(boundsRegion);
             Region& newDirtyRegion(dirtyIn ? *dirtyIn : scratch);
+            newDirtyRegion &= boundsRegion;
 
-            if (mNeedFullUpdate) {
-                // reset newDirtyRegion to bounds when a buffer is reallocated
-                // it would be better if this information was associated with
-                // the buffer and made available to outside of Surface.
-                // This will do for now though.
-                mNeedFullUpdate = false;
-                newDirtyRegion.set(bounds);
-            } else {
-                newDirtyRegion.andSelf(bounds);
-            }
-
+            // figure out if we can copy the frontbuffer back
             const sp<GraphicBuffer>& frontBuffer(mPostedBuffer);
-            if (frontBuffer !=0 &&
-                backBuffer->width  == frontBuffer->width && 
-                backBuffer->height == frontBuffer->height &&
-                !(mFlags & ISurfaceComposer::eDestroyBackbuffer)) 
-            {
+            const bool canCopyBack = (frontBuffer != 0 &&
+                    backBuffer->width  == frontBuffer->width &&
+                    backBuffer->height == frontBuffer->height &&
+                    backBuffer->format == frontBuffer->format &&
+                    !(mFlags & ISurfaceComposer::eDestroyBackbuffer));
+
+            // the dirty region we report to surfaceflinger is the one
+            // given by the user (as opposed to the one *we* return to the
+            // user).
+            mDirtyRegion = newDirtyRegion;
+
+            if (canCopyBack) {
+                // copy the area that is invalid and not repainted this round
                 const Region copyback(mOldDirtyRegion.subtract(newDirtyRegion));
-                if (!copyback.isEmpty() && frontBuffer!=0) {
-                    // copy front to back
+                if (!copyback.isEmpty())
                     copyBlt(backBuffer, frontBuffer, copyback);
-                }
+            } else {
+                // if we can't copy-back anything, modify the user's dirty
+                // region to make sure they redraw the whole buffer
+                newDirtyRegion = boundsRegion;
             }
 
-            mDirtyRegion = newDirtyRegion;
+            // keep track of the are of the buffer that is "clean"
+            // (ie: that will be redrawn)
             mOldDirtyRegion = newDirtyRegion;
 
             void* vaddr;
@@ -777,7 +946,7 @@
     
     err = queueBuffer(mLockedBuffer.get());
     LOGE_IF(err, "queueBuffer (idx=%d) failed (%s)",
-            mLockedBuffer->getIndex(), strerror(-err));
+            getBufferIndex(mLockedBuffer), strerror(-err));
 
     mPostedBuffer = mLockedBuffer;
     mLockedBuffer = 0;
@@ -789,7 +958,13 @@
     mSwapRectangle = r;
 }
 
-status_t Surface::getBufferLocked(int index, int usage)
+int Surface::getBufferIndex(const sp<GraphicBuffer>& buffer) const
+{
+    return buffer->getIndex();
+}
+
+status_t Surface::getBufferLocked(int index,
+        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
 {
     sp<ISurface> s(mSurface);
     if (s == 0) return NO_INIT;
@@ -797,20 +972,21 @@
     status_t err = NO_MEMORY;
 
     // free the current buffer
-    sp<GraphicBuffer>& currentBuffer(mBuffers[index]);
+    sp<GraphicBuffer>& currentBuffer(mBuffers.editItemAt(index));
     if (currentBuffer != 0) {
         getBufferMapper().unregisterBuffer(currentBuffer->handle);
         currentBuffer.clear();
     }
 
-    sp<GraphicBuffer> buffer = s->requestBuffer(index, usage);
+    sp<GraphicBuffer> buffer = s->requestBuffer(index, w, h, format, usage);
     LOGE_IF(buffer==0,
             "ISurface::getBuffer(%d, %08x) returned NULL",
             index, usage);
     if (buffer != 0) { // this should never happen by construction
         LOGE_IF(buffer->handle == NULL, 
-                "Surface (identity=%d) requestBuffer(%d, %08x) returned"
-                "a buffer with a null handle", mIdentity, index, usage);
+                "Surface (identity=%d) requestBuffer(%d, %u, %u, %u, %08x) "
+                "returned a buffer with a null handle",
+                mIdentity, index, w, h, format, usage);
         err = mSharedBufferClient->getStatus();
         LOGE_IF(err,  "Surface (identity=%d) state = %d", mIdentity, err);
         if (!err && buffer->handle != NULL) {
@@ -820,14 +996,51 @@
             if (err == NO_ERROR) {
                 currentBuffer = buffer;
                 currentBuffer->setIndex(index);
-                mNeedFullUpdate = true;
             }
         } else {
-            err = err<0 ? err : NO_MEMORY;
+            err = err<0 ? err : status_t(NO_MEMORY);
         }
     }
     return err; 
 }
 
-}; // namespace android
+// ----------------------------------------------------------------------------
+Surface::BufferInfo::BufferInfo()
+    : mWidth(0), mHeight(0), mFormat(0),
+      mUsage(GRALLOC_USAGE_HW_RENDER), mDirty(0)
+{
+}
 
+void Surface::BufferInfo::set(uint32_t w, uint32_t h, uint32_t format) {
+    if ((mWidth != w) || (mHeight != h) || (mFormat != format)) {
+        mWidth = w;
+        mHeight = h;
+        mFormat = format;
+        mDirty |= GEOMETRY;
+    }
+}
+
+void Surface::BufferInfo::set(uint32_t usage) {
+    mUsage = usage;
+}
+
+void Surface::BufferInfo::get(uint32_t *pWidth, uint32_t *pHeight,
+        uint32_t *pFormat, uint32_t *pUsage) const {
+    *pWidth  = mWidth;
+    *pHeight = mHeight;
+    *pFormat = mFormat;
+    *pUsage  = mUsage;
+}
+
+bool Surface::BufferInfo::validateBuffer(const sp<GraphicBuffer>& buffer) const {
+    // make sure we AT LEAST have the usage flags we want
+    if (mDirty || buffer==0 ||
+            ((buffer->usage & mUsage) != mUsage)) {
+        mDirty = 0;
+        return false;
+    }
+    return true;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/surfaceflinger_client/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
index 85167da..4096ac6 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -17,98 +17,137 @@
 #define LOG_TAG "SurfaceComposerClient"
 
 #include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 
-#include <cutils/memory.h>
-
-#include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/threads.h>
-#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
 #include <utils/Log.h>
+#include <utils/Singleton.h>
 
 #include <binder/IServiceManager.h>
 #include <binder/IMemory.h>
 
 #include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
 
 #include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
 #include <private/surfaceflinger/LayerState.h>
 #include <private/surfaceflinger/SharedBufferStack.h>
 
-#define VERBOSE(...)	((void)0)
-//#define VERBOSE			LOGD
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
 namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
+
+ComposerService::ComposerService()
+: Singleton<ComposerService>() {
+    const String16 name("SurfaceFlinger");
+    while (getService(name, &mComposerService) != NO_ERROR) {
+        usleep(250000);
+    }
+    mServerCblkMemory = mComposerService->getCblk();
+    mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
+            mServerCblkMemory->getBase());
+}
+
+sp<ISurfaceComposer> ComposerService::getComposerService() {
+    return ComposerService::getInstance().mComposerService;
+}
+
+surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
+    return ComposerService::getInstance().mServerCblk;
+}
+
+static inline sp<ISurfaceComposer> getComposerService() {
+    return ComposerService::getComposerService();
+}
+
+static inline surface_flinger_cblk_t const volatile * get_cblk() {
+    return ComposerService::getControlBlock();
+}
 
 // ---------------------------------------------------------------------------
 
-// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
-static Mutex                                                gLock;
-static sp<ISurfaceComposer>                                 gSurfaceManager;
-static DefaultKeyedVector< sp<IBinder>, wp<SurfaceComposerClient> > gActiveConnections;
-static SortedVector<sp<SurfaceComposerClient> >             gOpenTransactions;
-static sp<IMemoryHeap>                                      gServerCblkMemory;
-static volatile surface_flinger_cblk_t*                     gServerCblk;
-
-static sp<ISurfaceComposer> getComposerService()
+class Composer : public Singleton<Composer>
 {
-    sp<ISurfaceComposer> sc;
-    Mutex::Autolock _l(gLock);
-    if (gSurfaceManager != 0) {
-        sc = gSurfaceManager;
-    } else {
-        // release the lock while we're waiting...
-        gLock.unlock();
+    Mutex mLock;
+    SortedVector< wp<SurfaceComposerClient> > mActiveConnections;
+    SortedVector<sp<SurfaceComposerClient> > mOpenTransactions;
 
-        sp<IBinder> binder;
-        sp<IServiceManager> sm = defaultServiceManager();
-        do {
-            binder = sm->getService(String16("SurfaceFlinger"));
-            if (binder == 0) {
-                LOGW("SurfaceFlinger not published, waiting...");
-                usleep(500000); // 0.5 s
+    Composer() : Singleton<Composer>() {
+    }
+
+    void addClientImpl(const sp<SurfaceComposerClient>& client) {
+        Mutex::Autolock _l(mLock);
+        mActiveConnections.add(client);
+    }
+
+    void removeClientImpl(const sp<SurfaceComposerClient>& client) {
+        Mutex::Autolock _l(mLock);
+        mActiveConnections.remove(client);
+    }
+
+    void openGlobalTransactionImpl()
+    {
+        Mutex::Autolock _l(mLock);
+        if (mOpenTransactions.size()) {
+            LOGE("openGlobalTransaction() called more than once. skipping.");
+            return;
+        }
+        const size_t N = mActiveConnections.size();
+        for (size_t i=0; i<N; i++) {
+            sp<SurfaceComposerClient> client(mActiveConnections[i].promote());
+            if (client != 0 && mOpenTransactions.indexOf(client) < 0) {
+                if (client->openTransaction() == NO_ERROR) {
+                    mOpenTransactions.add(client);
+                } else {
+                    LOGE("openTransaction on client %p failed", client.get());
+                    // let it go, it'll fail later when the user
+                    // tries to do something with the transaction
+                }
             }
-        } while(binder == 0);
-
-        // grab the lock again for updating gSurfaceManager
-        gLock.lock();
-        if (gSurfaceManager == 0) {
-            sc = interface_cast<ISurfaceComposer>(binder);
-            gSurfaceManager = sc;
-        } else {
-            sc = gSurfaceManager;
         }
     }
-    return sc;
-}
 
-static volatile surface_flinger_cblk_t const * get_cblk()
-{
-    if (gServerCblk == 0) {
+    void closeGlobalTransactionImpl()
+    {
+        mLock.lock();
+            SortedVector< sp<SurfaceComposerClient> > clients(mOpenTransactions);
+            mOpenTransactions.clear();
+        mLock.unlock();
+
         sp<ISurfaceComposer> sm(getComposerService());
-        Mutex::Autolock _l(gLock);
-        if (gServerCblk == 0) {
-            gServerCblkMemory = sm->getCblk();
-            LOGE_IF(gServerCblkMemory==0, "Can't get server control block");
-            gServerCblk = (surface_flinger_cblk_t *)gServerCblkMemory->getBase();
-            LOGE_IF(gServerCblk==0, "Can't get server control block address");
-        }
+        sm->openGlobalTransaction();
+            const size_t N = clients.size();
+            for (size_t i=0; i<N; i++) {
+                clients[i]->closeTransaction();
+            }
+        sm->closeGlobalTransaction();
     }
-    return gServerCblk;
-}
+
+    friend class Singleton<Composer>;
+
+public:
+    static void addClient(const sp<SurfaceComposerClient>& client) {
+        Composer::getInstance().addClientImpl(client);
+    }
+    static void removeClient(const sp<SurfaceComposerClient>& client) {
+        Composer::getInstance().removeClientImpl(client);
+    }
+    static void openGlobalTransaction() {
+        Composer::getInstance().openGlobalTransactionImpl();
+    }
+    static void closeGlobalTransaction() {
+        Composer::getInstance().closeGlobalTransactionImpl();
+    }
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(Composer);
 
 // ---------------------------------------------------------------------------
 
@@ -120,61 +159,27 @@
 }
 
 SurfaceComposerClient::SurfaceComposerClient()
+    : mTransactionOpen(0), mPrebuiltLayerState(0), mStatus(NO_INIT)
+{
+}
+
+void SurfaceComposerClient::onFirstRef()
 {
     sp<ISurfaceComposer> sm(getComposerService());
-    if (sm == 0) {
-        _init(0, 0);
-        return;
+    if (sm != 0) {
+        sp<ISurfaceComposerClient> conn = sm->createConnection();
+        if (conn != 0) {
+            mClient = conn;
+            Composer::addClient(this);
+            mPrebuiltLayerState = new layer_state_t;
+            mStatus = NO_ERROR;
+        }
     }
-
-    _init(sm, sm->createConnection());
-
-    if (mClient != 0) {
-        Mutex::Autolock _l(gLock);
-        VERBOSE("Adding client %p to map", this);
-        gActiveConnections.add(mClient->asBinder(), this);
-    }
-}
-
-SurfaceComposerClient::SurfaceComposerClient(
-        const sp<ISurfaceComposer>& sm, const sp<IBinder>& conn)
-{
-    _init(sm, interface_cast<ISurfaceFlingerClient>(conn));
-}
-
-
-status_t SurfaceComposerClient::linkToComposerDeath(
-        const sp<IBinder::DeathRecipient>& recipient,
-        void* cookie, uint32_t flags)
-{
-    sp<ISurfaceComposer> sm(getComposerService());
-    return sm->asBinder()->linkToDeath(recipient, cookie, flags);    
-}
-
-void SurfaceComposerClient::_init(
-        const sp<ISurfaceComposer>& sm, const sp<ISurfaceFlingerClient>& conn)
-{
-    VERBOSE("Creating client %p, conn %p", this, conn.get());
-
-    mPrebuiltLayerState = 0;
-    mTransactionOpen = 0;
-    mStatus = NO_ERROR;
-    mControl = 0;
-
-    mClient = conn;
-    if (mClient == 0) {
-        mStatus = NO_INIT;
-        return;
-    }
-
-    mControlMemory = mClient->getControlBlock();
-    mSignalServer = sm;
-    mControl = static_cast<SharedClient *>(mControlMemory->getBase());
 }
 
 SurfaceComposerClient::~SurfaceComposerClient()
 {
-    VERBOSE("Destroying client %p, conn %p", this, mClient.get());
+    delete mPrebuiltLayerState;
     dispose();
 }
 
@@ -188,69 +193,31 @@
     return (mClient != 0) ? mClient->asBinder() : 0;
 }
 
-sp<SurfaceComposerClient>
-SurfaceComposerClient::clientForConnection(const sp<IBinder>& conn)
+status_t SurfaceComposerClient::linkToComposerDeath(
+        const sp<IBinder::DeathRecipient>& recipient,
+        void* cookie, uint32_t flags)
 {
-    sp<SurfaceComposerClient> client;
-
-    { // scope for lock
-        Mutex::Autolock _l(gLock);
-        client = gActiveConnections.valueFor(conn).promote();
-    }
-
-    if (client == 0) {
-        // Need to make a new client.
-        sp<ISurfaceComposer> sm(getComposerService());
-        client = new SurfaceComposerClient(sm, conn);
-        if (client != 0 && client->initCheck() == NO_ERROR) {
-            Mutex::Autolock _l(gLock);
-            gActiveConnections.add(conn, client);
-            //LOGD("we have %d connections", gActiveConnections.size());
-        } else {
-            client.clear();
-        }
-    }
-
-    return client;
+    sp<ISurfaceComposer> sm(getComposerService());
+    return sm->asBinder()->linkToDeath(recipient, cookie, flags);
 }
 
 void SurfaceComposerClient::dispose()
 {
     // this can be called more than once.
-
-    sp<IMemoryHeap>             controlMemory;
-    sp<ISurfaceFlingerClient>   client;
-
-    {
-        Mutex::Autolock _lg(gLock);
-        Mutex::Autolock _lm(mLock);
-
-        mSignalServer = 0;
-
-        if (mClient != 0) {
-            client = mClient;
-            mClient.clear();
-
-            ssize_t i = gActiveConnections.indexOfKey(client->asBinder());
-            if (i >= 0 && gActiveConnections.valueAt(i) == this) {
-                VERBOSE("Removing client %p from map at %d", this, int(i));
-                gActiveConnections.removeItemsAt(i);
-            }
-        }
-
-        delete mPrebuiltLayerState;
-        mPrebuiltLayerState = 0;
-        controlMemory = mControlMemory;
-        mControlMemory.clear();
-        mControl = 0;
-        mStatus = NO_INIT;
+    sp<ISurfaceComposerClient> client;
+    Mutex::Autolock _lm(mLock);
+    if (mClient != 0) {
+        Composer::removeClient(this);
+        client = mClient; // hold ref while lock is held
+        mClient.clear();
     }
+    mStatus = NO_INIT;
 }
 
 status_t SurfaceComposerClient::getDisplayInfo(
         DisplayID dpy, DisplayInfo* info)
 {
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
         return BAD_VALUE;
 
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
@@ -268,7 +235,7 @@
 
 ssize_t SurfaceComposerClient::getDisplayWidth(DisplayID dpy)
 {
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
         return BAD_VALUE;
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
@@ -277,7 +244,7 @@
 
 ssize_t SurfaceComposerClient::getDisplayHeight(DisplayID dpy)
 {
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
         return BAD_VALUE;
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
@@ -286,7 +253,7 @@
 
 ssize_t SurfaceComposerClient::getDisplayOrientation(DisplayID dpy)
 {
-    if (uint32_t(dpy)>=NUM_DISPLAY_MAX)
+    if (uint32_t(dpy)>=SharedBufferStack::NUM_DISPLAY_MAX)
         return BAD_VALUE;
     volatile surface_flinger_cblk_t const * cblk = get_cblk();
     volatile display_cblk_t const * dcblk = cblk->displays + dpy;
@@ -305,12 +272,6 @@
     return n;
 }
 
-
-void SurfaceComposerClient::signalServer()
-{
-    mSignalServer->signal();
-}
-
 sp<SurfaceControl> SurfaceComposerClient::createSurface(
         int pid,
         DisplayID display,
@@ -327,7 +288,6 @@
 
     return SurfaceComposerClient::createSurface(pid, name, display,
             w, h, format, flags);
-
 }
 
 sp<SurfaceControl> SurfaceComposerClient::createSurface(
@@ -341,13 +301,11 @@
 {
     sp<SurfaceControl> result;
     if (mStatus == NO_ERROR) {
-        ISurfaceFlingerClient::surface_data_t data;
+        ISurfaceComposerClient::surface_data_t data;
         sp<ISurface> surface = mClient->createSurface(&data, pid, name,
                 display, w, h, format, flags);
         if (surface != 0) {
-            if (uint32_t(data.token) < NUM_LAYERS_MAX) {
-                result = new SurfaceControl(this, surface, data, w, h, format, flags);
-            }
+            result = new SurfaceControl(this, surface, data, w, h, format, flags);
         }
     }
     return result;
@@ -373,56 +331,14 @@
 
 void SurfaceComposerClient::openGlobalTransaction()
 {
-    Mutex::Autolock _l(gLock);
-
-    if (gOpenTransactions.size()) {
-        LOGE("openGlobalTransaction() called more than once. skipping.");
-        return;
-    }
-
-    const size_t N = gActiveConnections.size();
-    VERBOSE("openGlobalTransaction (%ld clients)", N);
-    for (size_t i=0; i<N; i++) {
-        sp<SurfaceComposerClient> client(gActiveConnections.valueAt(i).promote());
-        if (client != 0 && gOpenTransactions.indexOf(client) < 0) {
-            if (client->openTransaction() == NO_ERROR) {
-                if (gOpenTransactions.add(client) < 0) {
-                    // Ooops!
-                    LOGE(   "Unable to add a SurfaceComposerClient "
-                            "to the global transaction set (out of memory?)");
-                    client->closeTransaction();
-                    // let it go, it'll fail later when the user
-                    // tries to do something with the transaction
-                }
-            } else {
-                LOGE("openTransaction on client %p failed", client.get());
-                // let it go, it'll fail later when the user
-                // tries to do something with the transaction
-            }
-        }
-    }
+    Composer::openGlobalTransaction();
 }
 
 void SurfaceComposerClient::closeGlobalTransaction()
 {
-    gLock.lock();
-        SortedVector< sp<SurfaceComposerClient> > clients(gOpenTransactions);
-        gOpenTransactions.clear();
-    gLock.unlock();
-
-    const size_t N = clients.size();
-    VERBOSE("closeGlobalTransaction (%ld clients)", N);
-
-    sp<ISurfaceComposer> sm(getComposerService());
-    sm->openGlobalTransaction();
-    for (size_t i=0; i<N; i++) {
-        clients[i]->closeTransaction();
-    }
-    sm->closeGlobalTransaction();
-
+    Composer::closeGlobalTransaction();
 }
 
-
 status_t SurfaceComposerClient::freezeDisplay(DisplayID dpy, uint32_t flags)
 {
     sp<ISurfaceComposer> sm(getComposerService());
@@ -447,26 +363,16 @@
     if (mStatus != NO_ERROR)
         return mStatus;
     Mutex::Autolock _l(mLock);
-    VERBOSE(   "openTransaction (client %p, mTransactionOpen=%d)",
-            this, mTransactionOpen);
     mTransactionOpen++;
-    if (mPrebuiltLayerState == 0) {
-        mPrebuiltLayerState = new layer_state_t;
-    }
     return NO_ERROR;
 }
 
-
 status_t SurfaceComposerClient::closeTransaction()
 {
     if (mStatus != NO_ERROR)
         return mStatus;
 
     Mutex::Autolock _l(mLock);
-
-    VERBOSE(   "closeTransaction (client %p, mTransactionOpen=%d)",
-            this, mTransactionOpen);
-
     if (mTransactionOpen <= 0) {
         LOGE(   "closeTransaction (client %p, mTransactionOpen=%d) "
                 "called more times than openTransaction()",
@@ -488,7 +394,7 @@
     return NO_ERROR;
 }
 
-layer_state_t* SurfaceComposerClient::_get_state_l(SurfaceID index)
+layer_state_t* SurfaceComposerClient::get_state_l(SurfaceID index)
 {
     // API usage error, do nothing.
     if (mTransactionOpen<=0) {
@@ -498,7 +404,7 @@
     }
 
     // use mPrebuiltLayerState just to find out if we already have it
-    layer_state_t& dummy = *mPrebuiltLayerState;
+    layer_state_t& dummy(*mPrebuiltLayerState);
     dummy.surface = index;
     ssize_t i = mStates.indexOf(dummy);
     if (i < 0) {
@@ -508,49 +414,49 @@
     return mStates.editArray() + i;
 }
 
-layer_state_t* SurfaceComposerClient::_lockLayerState(SurfaceID id)
+layer_state_t* SurfaceComposerClient::lockLayerState(SurfaceID id)
 {
     layer_state_t* s;
     mLock.lock();
-    s = _get_state_l(id);
+    s = get_state_l(id);
     if (!s) mLock.unlock();
     return s;
 }
 
-void SurfaceComposerClient::_unlockLayerState()
+void SurfaceComposerClient::unlockLayerState()
 {
     mLock.unlock();
 }
 
 status_t SurfaceComposerClient::setPosition(SurfaceID id, int32_t x, int32_t y)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::ePositionChanged;
     s->x = x;
     s->y = y;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
 status_t SurfaceComposerClient::setSize(SurfaceID id, uint32_t w, uint32_t h)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eSizeChanged;
     s->w = w;
     s->h = h;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
 status_t SurfaceComposerClient::setLayer(SurfaceID id, int32_t z)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eLayerChanged;
     s->z = z;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
@@ -579,34 +485,34 @@
 status_t SurfaceComposerClient::setFlags(SurfaceID id,
         uint32_t flags, uint32_t mask)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eVisibilityChanged;
     s->flags &= ~mask;
     s->flags |= (flags & mask);
     s->mask |= mask;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
 status_t SurfaceComposerClient::setTransparentRegionHint(
         SurfaceID id, const Region& transparentRegion)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eTransparentRegionChanged;
     s->transparentRegion = transparentRegion;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
 status_t SurfaceComposerClient::setAlpha(SurfaceID id, float alpha)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eAlphaChanged;
     s->alpha = alpha;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
@@ -615,7 +521,7 @@
         float dsdx, float dtdx,
         float dsdy, float dtdy )
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eMatrixChanged;
     layer_state_t::matrix22_t matrix;
@@ -624,19 +530,20 @@
     matrix.dsdy = dsdy;
     matrix.dtdy = dtdy;
     s->matrix = matrix;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
 status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eFreezeTintChanged;
     s->tint = tint;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
+// ----------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/libs/surfaceflinger_client/tests/Android.mk b/libs/surfaceflinger_client/tests/Android.mk
new file mode 100644
index 0000000..5053e7d
--- /dev/null
+++ b/libs/surfaceflinger_client/tests/Android.mk
@@ -0,0 +1 @@
+include $(call all-subdir-makefiles)
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk b/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk
new file mode 100644
index 0000000..d3dfe04
--- /dev/null
+++ b/libs/surfaceflinger_client/tests/SharedBufferStack/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	SharedBufferStackTest.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui \
+    libsurfaceflinger_client
+
+LOCAL_MODULE:= test-sharedbufferstack
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
new file mode 100644
index 0000000..f409f48
--- /dev/null
+++ b/libs/surfaceflinger_client/tests/SharedBufferStack/SharedBufferStackTest.cpp
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 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.
+ */
+
+#undef NDEBUG
+
+#include <assert.h>
+#include <cutils/memory.h>
+#include <cutils/log.h>
+#include <utils/Errors.h>
+#include <private/surfaceflinger/SharedBufferStack.h>
+
+using namespace android;
+
+void log(const char* prefix, int *b, size_t num);
+void test0(SharedBufferServer& s, SharedBufferClient& c, size_t num, int* list);
+
+// ----------------------------------------------------------------------------
+
+int main(int argc, char** argv)
+{
+    SharedClient client;
+    SharedBufferServer s(&client, 0, 4, 0);
+    SharedBufferClient c(&client, 0, 4, 0);
+
+    printf("basic test 0\n");
+    int list0[4] = {0, 1, 2, 3};
+    test0(s, c, 4, list0);
+
+    printf("basic test 1\n");
+    int list1[4] = {2, 1, 0, 3};
+    test0(s, c, 4, list1);
+
+    int b = c.dequeue();
+    c.lock(b);
+    c.queue(b);
+    s.retireAndLock();
+
+    printf("basic test 2\n");
+    int list2[4] = {1, 2, 3, 0};
+    test0(s, c, 4, list2);
+
+
+    printf("resize test\n");
+    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
+        SharedBufferServer& s;
+        virtual status_t operator()(int bufferCount) const {
+            return s.resize(bufferCount);
+        }
+    public:
+        SetBufferCountIPC(SharedBufferServer& s) : s(s) { }
+    } resize(s);
+
+    c.setBufferCount(6, resize);
+    int list3[6] = {3, 2, 1, 4, 5, 0};
+    test0(s, c, 6, list3);
+
+    return 0;
+}
+
+void log(const char* prefix, int *b, size_t num)
+{
+    printf("%s: ", prefix);
+    for (size_t i=0 ; i<num ; i++) {
+        printf("%d ", b[i]);
+    }
+    printf("\n");
+}
+
+// ----------------------------------------------------------------------------
+
+void test0(
+        SharedBufferServer& s,
+        SharedBufferClient& c,
+        size_t num,
+        int* list)
+{
+    status_t err;
+    int b[num], u[num], r[num];
+
+    for (size_t i=0 ; i<num ; i++) {
+        b[i] = c.dequeue();
+        assert(b[i]==list[i]);
+    }
+    log("DQ", b, num);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.lock(b[i]);
+        assert(err==0);
+    }
+    log("LK", b, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.queue(b[i]);
+        assert(err==0);
+    }
+    log(" Q", b, num-1);
+
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        r[i] = s.retireAndLock();
+        assert(r[i]==list[i]);
+        err = s.unlock(r[i]);
+        assert(err == 0);
+    }
+    log("RT", r, num-1);
+
+    err = c.lock(b[num-1]);
+    assert(err == 0);
+    log("LK", b+num-1, 1);
+
+    err = c.queue(b[num-1]);
+    assert(err == 0);
+    log(" Q", b+num-1, 1);
+
+    r[num-1] = s.retireAndLock();
+    assert(r[num-1]==list[num-1]);
+    err = s.unlock(r[num-1]);
+    assert(err == 0);
+    log("RT", r+num-1, 1);
+
+    // ------------------------------------
+    printf("\n");
+
+    for (size_t i=0 ; i<num ; i++) {
+        b[i] = c.dequeue();
+        assert(b[i]==list[i]);
+    }
+    log("DQ", b, num);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.lock(b[i]);
+        assert(err==0);
+    }
+    log("LK", b, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        u[i] = b[num-2-i];
+    }
+    u[num-1] = b[num-1];
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.queue(u[i]);
+        assert(err==0);
+    }
+    log(" Q", u, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        r[i] = s.retireAndLock();
+        assert(r[i]==u[i]);
+        err = s.unlock(r[i]);
+        assert(err == 0);
+    }
+    log("RT", r, num-1);
+
+    err = c.lock(b[num-1]);
+    assert(err == 0);
+    log("LK", b+num-1, 1);
+
+    err = c.queue(b[num-1]);
+    assert(err == 0);
+    log(" Q", b+num-1, 1);
+
+    r[num-1] = s.retireAndLock();
+    assert(r[num-1]==list[num-1]);
+    err = s.unlock(r[num-1]);
+    assert(err == 0);
+    log("RT", r+num-1, 1);
+
+    // ------------------------------------
+    printf("\n");
+
+    for (size_t i=0 ; i<num ; i++) {
+        b[i] = c.dequeue();
+        assert(b[i]==u[i]);
+    }
+    log("DQ", b, num);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.lock(b[i]);
+        assert(err==0);
+    }
+    log("LK", b, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.queue(b[i]);
+        assert(err==0);
+    }
+    log(" Q", b, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        r[i] = s.retireAndLock();
+        assert(r[i]==u[i]);
+        err = s.unlock(r[i]);
+        assert(err == 0);
+    }
+    log("RT", r, num-1);
+
+    err = c.lock(u[num-1]);
+    assert(err == 0);
+    log("LK", u+num-1, 1);
+
+    err = c.queue(u[num-1]);
+    assert(err == 0);
+    log(" Q", u+num-1, 1);
+
+    r[num-1] = s.retireAndLock();
+    assert(r[num-1]==u[num-1]);
+    err = s.unlock(r[num-1]);
+    assert(err == 0);
+    log("RT", r+num-1, 1);
+
+    // ------------------------------------
+    printf("\n");
+
+    b[0] = c.dequeue();
+    assert(b[0]==u[0]);
+    log("DQ", b, 1);
+
+    c.undoDequeue(b[0]);
+    assert(err == 0);
+    log("UDQ", b, 1);
+
+    // ------------------------------------
+    printf("\n");
+
+    for (size_t i=0 ; i<num ; i++) {
+        b[i] = c.dequeue();
+        assert(b[i]==u[i]);
+    }
+    log("DQ", b, num);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.lock(b[i]);
+        assert(err==0);
+    }
+    log("LK", b, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        err = c.queue(b[i]);
+        assert(err==0);
+    }
+    log(" Q", b, num-1);
+
+    for (size_t i=0 ; i<num-1 ; i++) {
+        r[i] = s.retireAndLock();
+        assert(r[i]==u[i]);
+        err = s.unlock(r[i]);
+        assert(err == 0);
+    }
+    log("RT", r, num-1);
+
+    err = c.lock(u[num-1]);
+    assert(err == 0);
+    log("LK", u+num-1, 1);
+
+    err = c.queue(u[num-1]);
+    assert(err == 0);
+    log(" Q", u+num-1, 1);
+
+    r[num-1] = s.retireAndLock();
+    assert(r[num-1]==u[num-1]);
+    err = s.unlock(r[num-1]);
+    assert(err == 0);
+    log("RT", r+num-1, 1);
+    printf("\n");
+}
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index f7acd97..9f49348 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -11,6 +11,11 @@
 	GraphicBufferMapper.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
+	Input.cpp \
+	InputDispatcher.cpp \
+	InputManager.cpp \
+	InputReader.cpp \
+	InputTransport.cpp \
 	IOverlay.cpp \
 	Overlay.cpp \
 	PixelFormat.cpp \
@@ -33,3 +38,13 @@
 endif
 
 include $(BUILD_SHARED_LIBRARY)
+
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 2d4c2e2..1d38b4b 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -54,6 +54,9 @@
  */
 #define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
 
+/* this macro computes the number of bytes needed to represent a bit array of the specified size */
+#define sizeof_bit_array(bits)  ((bits + 7) / 8)
+
 #define ID_MASK  0x0000ffff
 #define SEQ_MASK 0x7fff0000
 #define SEQ_SHIFT 16
@@ -96,6 +99,7 @@
     , mDevicesById(0), mNumDevicesById(0)
     , mOpeningDevices(0), mClosingDevices(0)
     , mDevices(0), mFDs(0), mFDCount(0), mOpened(false)
+    , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0)
 {
     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
 #ifdef EV_SW
@@ -133,9 +137,10 @@
     return device->classes;
 }
 
-int EventHub::getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
-        int* outMaxValue, int* outFlat, int* outFuzz) const
-{
+status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
+        RawAbsoluteAxisInfo* outAxisInfo) const {
+    outAxisInfo->clear();
+
     AutoMutex _l(mLock);
     device_t* device = getDevice(deviceId);
     if (device == NULL) return -1;
@@ -143,87 +148,58 @@
     struct input_absinfo info;
 
     if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
-        LOGE("Error reading absolute controller %d for device %s fd %d\n",
+        LOGW("Error reading absolute controller %d for device %s fd %d\n",
              axis, device->name.string(), device->fd);
-        return -1;
+        return -errno;
     }
 
-    *outMinValue = info.minimum;
-    *outMaxValue = info.maximum;
-    *outFlat = info.flat;
-    *outFuzz = info.fuzz;
-    return 0;
+    if (info.minimum != info.maximum) {
+        outAxisInfo->valid = true;
+        outAxisInfo->minValue = info.minimum;
+        outAxisInfo->maxValue = info.maximum;
+        outAxisInfo->flat = info.flat;
+        outAxisInfo->fuzz = info.fuzz;
+    }
+    return OK;
 }
 
-int EventHub::getSwitchState(int sw) const
-{
-#ifdef EV_SW
-    if (sw >= 0 && sw <= SW_MAX) {
-        int32_t devid = mSwitches[sw];
-        if (devid != 0) {
-            return getSwitchState(devid, sw);
+int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const {
+    if (scanCode >= 0 && scanCode <= KEY_MAX) {
+        AutoMutex _l(mLock);
+
+        device_t* device = getDevice(deviceId);
+        if (device != NULL) {
+            return getScanCodeStateLocked(device, scanCode);
         }
     }
-#endif
-    return -1;
+    return AKEY_STATE_UNKNOWN;
 }
 
-int EventHub::getSwitchState(int32_t deviceId, int sw) const
-{
-#ifdef EV_SW
-    AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
-    if (device == NULL) return -1;
-    
-    if (sw >= 0 && sw <= SW_MAX) {
-        uint8_t sw_bitmask[(SW_MAX+7)/8];
-        memset(sw_bitmask, 0, sizeof(sw_bitmask));
-        if (ioctl(device->fd, EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
-            return test_bit(sw, sw_bitmask) ? 1 : 0;
-        }
+int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) const {
+    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
+    memset(key_bitmask, 0, sizeof(key_bitmask));
+    if (ioctl(device->fd,
+               EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
+        return test_bit(scanCode, key_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
     }
-#endif
-    
-    return -1;
+    return AKEY_STATE_UNKNOWN;
 }
 
-int EventHub::getScancodeState(int code) const
-{
-    return getScancodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getScancodeState(int32_t deviceId, int code) const
-{
+int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
     AutoMutex _l(mLock);
+
     device_t* device = getDevice(deviceId);
-    if (device == NULL) return -1;
-    
-    if (code >= 0 && code <= KEY_MAX) {
-        uint8_t key_bitmask[(KEY_MAX+7)/8];
-        memset(key_bitmask, 0, sizeof(key_bitmask));
-        if (ioctl(device->fd, EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
-            return test_bit(code, key_bitmask) ? 1 : 0;
-        }
+    if (device != NULL) {
+        return getKeyCodeStateLocked(device, keyCode);
     }
-    
-    return -1;
+    return AKEY_STATE_UNKNOWN;
 }
 
-int EventHub::getKeycodeState(int code) const
-{
-    return getKeycodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getKeycodeState(int32_t deviceId, int code) const
-{
-    AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
-    if (device == NULL || device->layoutMap == NULL) return -1;
-    
+int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const {
     Vector<int32_t> scanCodes;
-    device->layoutMap->findScancodes(code, &scanCodes);
-    
-    uint8_t key_bitmask[(KEY_MAX+7)/8];
+    device->layoutMap->findScancodes(keyCode, &scanCodes);
+
+    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
     memset(key_bitmask, 0, sizeof(key_bitmask));
     if (ioctl(device->fd, EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
         #if 0
@@ -236,12 +212,72 @@
             int32_t sc = scanCodes.itemAt(i);
             //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
             if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
-                return 1;
+                return AKEY_STATE_DOWN;
+            }
+        }
+        return AKEY_STATE_UP;
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
+#ifdef EV_SW
+    if (sw >= 0 && sw <= SW_MAX) {
+        AutoMutex _l(mLock);
+
+        device_t* device = getDevice(deviceId);
+        if (device != NULL) {
+            return getSwitchStateLocked(device, sw);
+        }
+    }
+#endif
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const {
+    uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
+    memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    if (ioctl(device->fd,
+               EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
+        return test_bit(sw, sw_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) const {
+    AutoMutex _l(mLock);
+
+    device_t* device = getDevice(deviceId);
+    if (device != NULL) {
+        return markSupportedKeyCodesLocked(device, numCodes, keyCodes, outFlags);
+    }
+    return false;
+}
+
+bool EventHub::markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) const {
+    if (device->layoutMap == NULL || device->keyBitmask == NULL) {
+        return false;
+    }
+
+    Vector<int32_t> scanCodes;
+    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
+        scanCodes.clear();
+
+        status_t err = device->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
+        if (! err) {
+            // check the possible scan codes identified by the layout map against the
+            // map of codes actually emitted by the driver
+            for (size_t sc = 0; sc < scanCodes.size(); sc++) {
+                if (test_bit(scanCodes[sc], device->keyBitmask)) {
+                    outFlags[codeIndex] = 1;
+                    break;
+                }
             }
         }
     }
-    
-    return 0;
+    return true;
 }
 
 status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
@@ -292,27 +328,15 @@
     return NULL;
 }
 
-bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
-        int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
-        int32_t* outValue, nsecs_t* outWhen)
+bool EventHub::getEvent(RawEvent* outEvent)
 {
-    *outDeviceId = 0;
-    *outType = 0;
-    *outScancode = 0;
-    *outKeycode = 0;
-    *outFlags = 0;
-    *outValue = 0;
-    *outWhen = 0;
-
-    status_t err;
-
-    fd_set readfds;
-    int maxFd = -1;
-    int cc;
-    int i;
-    int res;
-    int pollres;
-    struct input_event iev;
+    outEvent->deviceId = 0;
+    outEvent->type = 0;
+    outEvent->scanCode = 0;
+    outEvent->keyCode = 0;
+    outEvent->flags = 0;
+    outEvent->value = 0;
+    outEvent->when = 0;
 
     // Note that we only allow one caller to getEvent(), so don't need
     // to do locking here...  only when adding/removing devices.
@@ -322,93 +346,127 @@
         mOpened = true;
     }
 
-    while(1) {
-
-        // First, report any devices that had last been added/removed.
+    for (;;) {
+        // Report any devices that had last been added/removed.
         if (mClosingDevices != NULL) {
             device_t* device = mClosingDevices;
             LOGV("Reporting device closed: id=0x%x, name=%s\n",
                  device->id, device->path.string());
             mClosingDevices = device->next;
-            *outDeviceId = device->id;
-            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
-            *outType = DEVICE_REMOVED;
+            if (device->id == mFirstKeyboardId) {
+                outEvent->deviceId = 0;
+            } else {
+                outEvent->deviceId = device->id;
+            }
+            outEvent->type = DEVICE_REMOVED;
             delete device;
             return true;
         }
+
         if (mOpeningDevices != NULL) {
             device_t* device = mOpeningDevices;
             LOGV("Reporting device opened: id=0x%x, name=%s\n",
                  device->id, device->path.string());
             mOpeningDevices = device->next;
-            *outDeviceId = device->id;
-            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
-            *outType = DEVICE_ADDED;
+            if (device->id == mFirstKeyboardId) {
+                outEvent->deviceId = 0;
+            } else {
+                outEvent->deviceId = device->id;
+            }
+            outEvent->type = DEVICE_ADDED;
             return true;
         }
 
-        release_wake_lock(WAKE_LOCK_ID);
+        // Grab the next input event.
+        for (;;) {
+            // Consume buffered input events, if any.
+            if (mInputBufferIndex < mInputBufferCount) {
+                const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
+                const device_t* device = mDevices[mInputDeviceIndex];
 
-        pollres = poll(mFDs, mFDCount, -1);
-
-        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
-        if (pollres <= 0) {
-            if (errno != EINTR) {
-                LOGW("select failed (errno=%d)\n", errno);
-                usleep(100000);
-            }
-            continue;
-        }
-
-        //printf("poll %d, returned %d\n", mFDCount, pollres);
-
-        // mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
-        for(i = 1; i < mFDCount; i++) {
-            if(mFDs[i].revents) {
-                LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
-                if(mFDs[i].revents & POLLIN) {
-                    res = read(mFDs[i].fd, &iev, sizeof(iev));
-                    if (res == sizeof(iev)) {
-                        LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
-                             mDevices[i]->path.string(),
-                             (int) iev.time.tv_sec, (int) iev.time.tv_usec,
-                             iev.type, iev.code, iev.value);
-                        *outDeviceId = mDevices[i]->id;
-                        if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
-                        *outType = iev.type;
-                        *outScancode = iev.code;
-                        if (iev.type == EV_KEY) {
-                            err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
-                            LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
-                                iev.code, *outKeycode, *outFlags, err);
-                            if (err != 0) {
-                                *outKeycode = 0;
-                                *outFlags = 0;
-                            }
-                        } else {
-                            *outKeycode = iev.code;
-                        }
-                        *outValue = iev.value;
-                        *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
-                        return true;
-                    } else {
-                        if (res<0) {
-                            LOGW("could not get event (errno=%d)", errno);
-                        } else {
-                            LOGE("could not get event (wrong size: %d)", res);
-                        }
-                        continue;
+                LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
+                     (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
+                if (device->id == mFirstKeyboardId) {
+                    outEvent->deviceId = 0;
+                } else {
+                    outEvent->deviceId = device->id;
+                }
+                outEvent->type = iev.type;
+                outEvent->scanCode = iev.code;
+                if (iev.type == EV_KEY) {
+                    status_t err = device->layoutMap->map(iev.code,
+                            & outEvent->keyCode, & outEvent->flags);
+                    LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
+                        iev.code, outEvent->keyCode, outEvent->flags, err);
+                    if (err != 0) {
+                        outEvent->keyCode = AKEYCODE_UNKNOWN;
+                        outEvent->flags = 0;
                     }
+                } else {
+                    outEvent->keyCode = iev.code;
+                }
+                outEvent->value = iev.value;
+
+                // Use an event timestamp in the same timebase as
+                // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
+                // as expected by the rest of the system.
+                outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
+                return true;
+            }
+
+            // Finish reading all events from devices identified in previous poll().
+            // This code assumes that mInputDeviceIndex is initially 0 and that the
+            // revents member of pollfd is initialized to 0 when the device is first added.
+            // Since mFDs[0] is used for inotify, we process regular events starting at index 1.
+            mInputDeviceIndex += 1;
+            if (mInputDeviceIndex >= mFDCount) {
+                mInputDeviceIndex = 0;
+                break;
+            }
+
+            const struct pollfd &pfd = mFDs[mInputDeviceIndex];
+            if (pfd.revents & POLLIN) {
+                int32_t readSize = read(pfd.fd, mInputBufferData,
+                        sizeof(struct input_event) * INPUT_BUFFER_SIZE);
+                if (readSize < 0) {
+                    if (errno != EAGAIN && errno != EINTR) {
+                        LOGW("could not get event (errno=%d)", errno);
+                    }
+                } else if ((readSize % sizeof(struct input_event)) != 0) {
+                    LOGE("could not get event (wrong size: %d)", readSize);
+                } else {
+                    mInputBufferCount = readSize / sizeof(struct input_event);
+                    mInputBufferIndex = 0;
                 }
             }
         }
-        
+
         // read_notify() will modify mFDs and mFDCount, so this must be done after
         // processing all other events.
         if(mFDs[0].revents & POLLIN) {
             read_notify(mFDs[0].fd);
         }
+
+        // Poll for events.  Mind the wake lock dance!
+        // We hold a wake lock at all times except during poll().  This works due to some
+        // subtle choreography.  When a device driver has pending (unread) events, it acquires
+        // a kernel wake lock.  However, once the last pending event has been read, the device
+        // driver will release the kernel wake lock.  To prevent the system from going to sleep
+        // when this happens, the EventHub holds onto its own user wake lock while the client
+        // is processing events.  Thus the system can only sleep if there are no events
+        // pending or currently being processed.
+        release_wake_lock(WAKE_LOCK_ID);
+
+        int pollResult = poll(mFDs, mFDCount, -1);
+
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+
+        if (pollResult <= 0) {
+            if (errno != EINTR) {
+                LOGW("select failed (errno=%d)\n", errno);
+                usleep(100000);
+            }
+        }
     }
 }
 
@@ -426,6 +484,7 @@
     mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
     mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
     mFDs[0].events = POLLIN;
+    mFDs[0].revents = 0;
     mDevices[0] = NULL;
 #ifdef HAVE_INOTIFY
     mFDs[0].fd = inotify_init();
@@ -450,37 +509,27 @@
     return true;
 }
 
-/*
- * Inspect the known devices to determine whether physical keys exist for the given
- * framework-domain key codes.
- */
-bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
-    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
-        outFlags[codeIndex] = 0;
+// ----------------------------------------------------------------------------
 
-        // check each available hardware device for support for this keycode
-        Vector<int32_t> scanCodes;
-        for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
-            if (mDevices[n]) {
-                status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
-                if (!err) {
-                    // check the possible scan codes identified by the layout map against the
-                    // map of codes actually emitted by the driver
-                    for (size_t sc = 0; sc < scanCodes.size(); sc++) {
-                        if (test_bit(scanCodes[sc], mDevices[n]->keyBitmask)) {
-                            outFlags[codeIndex] = 1;
-                            break;
-                        }
-                    }
-                }
-            }
+static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) {
+    const uint8_t* end = array + endIndex;
+    array += startIndex;
+    while (array != end) {
+        if (*(array++) != 0) {
+            return true;
         }
     }
-
-    return true;
+    return false;
 }
 
-// ----------------------------------------------------------------------------
+static const int32_t GAMEPAD_KEYCODES[] = {
+        AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C,
+        AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z,
+        AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1,
+        AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2,
+        AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR,
+        AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE
+};
 
 int EventHub::open_device(const char *deviceName)
 {
@@ -541,6 +590,12 @@
         idstr[0] = '\0';
     }
 
+    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
+        LOGE("Error %d making device file descriptor non-blocking.", errno);
+        close(fd);
+        return -1;
+    }
+
     int devid = 0;
     while (devid < mNumDevicesById) {
         if (mDevicesById[devid].device == NULL) {
@@ -598,28 +653,29 @@
     device->fd = fd;
     mFDs[mFDCount].fd = fd;
     mFDs[mFDCount].events = POLLIN;
+    mFDs[mFDCount].revents = 0;
 
-    // figure out the kinds of events the device reports
+    // Figure out the kinds of events the device reports.
     
-    // See if this is a keyboard, and classify it.  Note that we only
-    // consider up through the function keys; we don't want to include
-    // ones after that (play cd etc) so we don't mistakenly consider a
-    // controller to be a keyboard.
-    uint8_t key_bitmask[(KEY_MAX+7)/8];
+    uint8_t key_bitmask[sizeof_bit_array(KEY_MAX + 1)];
     memset(key_bitmask, 0, sizeof(key_bitmask));
+
     LOGV("Getting keys...");
     if (ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(key_bitmask)), key_bitmask) >= 0) {
         //LOGI("MAP\n");
-        //for (int i=0; i<((KEY_MAX+7)/8); i++) {
+        //for (int i = 0; i < sizeof(key_bitmask); i++) {
         //    LOGI("%d: 0x%02x\n", i, key_bitmask[i]);
         //}
-        for (int i=0; i<((BTN_MISC+7)/8); i++) {
-            if (key_bitmask[i] != 0) {
-                device->classes |= CLASS_KEYBOARD;
-                break;
-            }
-        }
-        if ((device->classes & CLASS_KEYBOARD) != 0) {
+
+        // See if this is a keyboard.  Ignore everything in the button range except for
+        // gamepads which are also considered keyboards.
+        if (containsNonZeroByte(key_bitmask, 0, sizeof_bit_array(BTN_MISC))
+                || containsNonZeroByte(key_bitmask, sizeof_bit_array(BTN_GAMEPAD),
+                        sizeof_bit_array(BTN_DIGI))
+                || containsNonZeroByte(key_bitmask, sizeof_bit_array(KEY_OK),
+                        sizeof_bit_array(KEY_MAX + 1))) {
+            device->classes |= INPUT_DEVICE_CLASS_KEYBOARD;
+
             device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
             if (device->keyBitmask != NULL) {
                 memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
@@ -631,53 +687,57 @@
         }
     }
     
-    // See if this is a trackball.
+    // See if this is a trackball (or mouse).
     if (test_bit(BTN_MOUSE, key_bitmask)) {
-        uint8_t rel_bitmask[(REL_MAX+7)/8];
+        uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
         memset(rel_bitmask, 0, sizeof(rel_bitmask));
         LOGV("Getting relative controllers...");
-        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
-        {
+        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) {
             if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
-                device->classes |= CLASS_TRACKBALL;
+                device->classes |= INPUT_DEVICE_CLASS_TRACKBALL;
             }
         }
     }
-    
-    uint8_t abs_bitmask[(ABS_MAX+7)/8];
+
+    // See if this is a touch pad.
+    uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
     memset(abs_bitmask, 0, sizeof(abs_bitmask));
     LOGV("Getting absolute controllers...");
-    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
-    
-    // Is this a new modern multi-touch driver?
-    if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
-            && test_bit(ABS_MT_POSITION_X, abs_bitmask)
-            && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
-        device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
-        
-    // Is this an old style single-touch driver?
-    } else if (test_bit(BTN_TOUCH, key_bitmask)
-            && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
-        device->classes |= CLASS_TOUCHSCREEN;
+    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
+        // Is this a new modern multi-touch driver?
+        if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
+                && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
+
+        // Is this an old style single-touch driver?
+        } else if (test_bit(BTN_TOUCH, key_bitmask)
+                && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
+            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN;
+        }
     }
 
 #ifdef EV_SW
     // figure out the switches this device reports
-    uint8_t sw_bitmask[(SW_MAX+7)/8];
+    uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
     memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    bool hasSwitches = false;
     if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
         for (int i=0; i<EV_SW; i++) {
             //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
             if (test_bit(i, sw_bitmask)) {
+                hasSwitches = true;
                 if (mSwitches[i] == 0) {
                     mSwitches[i] = device->id;
                 }
             }
         }
     }
+    if (hasSwitches) {
+        device->classes |= INPUT_DEVICE_CLASS_SWITCH;
+    }
 #endif
 
-    if ((device->classes&CLASS_KEYBOARD) != 0) {
+    if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
         char tmpfn[sizeof(name)];
         char keylayoutFilename[300];
 
@@ -699,7 +759,10 @@
                      "%s/usr/keylayout/%s", root, "qwerty.kl");
             defaultKeymap = true;
         }
-        device->layoutMap->load(keylayoutFilename);
+        status_t status = device->layoutMap->load(keylayoutFilename);
+        if (status) {
+            LOGE("Error %d loading key layout.", status);
+        }
 
         // tell the world about the devname (the descriptive name)
         if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name, "-keypad")) {
@@ -719,19 +782,27 @@
         property_set(propName, name);
 
         // 'Q' key support = cheap test of whether this is an alpha-capable kbd
-        if (hasKeycode(device, kKeyCodeQ)) {
-            device->classes |= CLASS_ALPHAKEY;
+        if (hasKeycode(device, AKEYCODE_Q)) {
+            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
         }
         
-        // See if this has a DPAD.
-        if (hasKeycode(device, kKeyCodeDpadUp) &&
-                hasKeycode(device, kKeyCodeDpadDown) &&
-                hasKeycode(device, kKeyCodeDpadLeft) &&
-                hasKeycode(device, kKeyCodeDpadRight) &&
-                hasKeycode(device, kKeyCodeDpadCenter)) {
-            device->classes |= CLASS_DPAD;
+        // See if this device has a DPAD.
+        if (hasKeycode(device, AKEYCODE_DPAD_UP) &&
+                hasKeycode(device, AKEYCODE_DPAD_DOWN) &&
+                hasKeycode(device, AKEYCODE_DPAD_LEFT) &&
+                hasKeycode(device, AKEYCODE_DPAD_RIGHT) &&
+                hasKeycode(device, AKEYCODE_DPAD_CENTER)) {
+            device->classes |= INPUT_DEVICE_CLASS_DPAD;
         }
         
+        // See if this device has a gamepad.
+        for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES); i++) {
+            if (hasKeycode(device, GAMEPAD_KEYCODES[i])) {
+                device->classes |= INPUT_DEVICE_CLASS_GAMEPAD;
+                break;
+            }
+        }
+
         LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
                 device->id, name, propName, keylayoutFilename);
     }
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 52380a0..6f8948d 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -67,7 +67,7 @@
  * This implements the (main) framebuffer management. This class is used
  * mostly by SurfaceFlinger, but also by command line GL application.
  * 
- * In fact this is an implementation of android_native_window_t on top of
+ * In fact this is an implementation of ANativeWindow on top of
  * the framebuffer.
  * 
  * Currently it is pretty simple, it manages only two buffers (the front and 
@@ -117,23 +117,23 @@
         LOGE_IF(err, "fb buffer 1 allocation failed w=%d, h=%d, err=%s",
                 fbDev->width, fbDev->height, strerror(-err));
 
-        const_cast<uint32_t&>(android_native_window_t::flags) = fbDev->flags; 
-        const_cast<float&>(android_native_window_t::xdpi) = fbDev->xdpi;
-        const_cast<float&>(android_native_window_t::ydpi) = fbDev->ydpi;
-        const_cast<int&>(android_native_window_t::minSwapInterval) = 
+        const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags; 
+        const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
+        const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
+        const_cast<int&>(ANativeWindow::minSwapInterval) = 
             fbDev->minSwapInterval;
-        const_cast<int&>(android_native_window_t::maxSwapInterval) = 
+        const_cast<int&>(ANativeWindow::maxSwapInterval) = 
             fbDev->maxSwapInterval;
     } else {
         LOGE("Couldn't get gralloc module");
     }
 
-    android_native_window_t::setSwapInterval = setSwapInterval;
-    android_native_window_t::dequeueBuffer = dequeueBuffer;
-    android_native_window_t::lockBuffer = lockBuffer;
-    android_native_window_t::queueBuffer = queueBuffer;
-    android_native_window_t::query = query;
-    android_native_window_t::perform = perform;
+    ANativeWindow::setSwapInterval = setSwapInterval;
+    ANativeWindow::dequeueBuffer = dequeueBuffer;
+    ANativeWindow::lockBuffer = lockBuffer;
+    ANativeWindow::queueBuffer = queueBuffer;
+    ANativeWindow::query = query;
+    ANativeWindow::perform = perform;
 }
 
 FramebufferNativeWindow::~FramebufferNativeWindow() 
@@ -168,13 +168,13 @@
 }
 
 int FramebufferNativeWindow::setSwapInterval(
-        android_native_window_t* window, int interval) 
+        ANativeWindow* window, int interval) 
 {
     framebuffer_device_t* fb = getSelf(window)->fbDev;
     return fb->setSwapInterval(fb, interval);
 }
 
-int FramebufferNativeWindow::dequeueBuffer(android_native_window_t* window, 
+int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, 
         android_native_buffer_t** buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
@@ -196,7 +196,7 @@
     return 0;
 }
 
-int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, 
+int FramebufferNativeWindow::lockBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
@@ -210,7 +210,7 @@
     return NO_ERROR;
 }
 
-int FramebufferNativeWindow::queueBuffer(android_native_window_t* window, 
+int FramebufferNativeWindow::queueBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
@@ -224,7 +224,7 @@
     return res;
 }
 
-int FramebufferNativeWindow::query(android_native_window_t* window,
+int FramebufferNativeWindow::query(ANativeWindow* window,
         int what, int* value) 
 {
     FramebufferNativeWindow* self = getSelf(window);
@@ -245,7 +245,7 @@
     return BAD_VALUE;
 }
 
-int FramebufferNativeWindow::perform(android_native_window_t* window,
+int FramebufferNativeWindow::perform(ANativeWindow* window,
         int operation, ...)
 {
     switch (operation) {
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index ba1fd9c..519c277 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -38,7 +38,7 @@
 
 GraphicBuffer::GraphicBuffer()
     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
+      mInitCheck(NO_ERROR), mIndex(-1)
 {
     width  = 
     height = 
@@ -51,7 +51,7 @@
 GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h, 
         PixelFormat reqFormat, uint32_t reqUsage)
     : BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
+      mInitCheck(NO_ERROR), mIndex(-1)
 {
     width  = 
     height = 
@@ -67,7 +67,7 @@
         uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
     : BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
       mBufferMapper(GraphicBufferMapper::get()),
-      mInitCheck(NO_ERROR),  mVStride(0), mIndex(-1)
+      mInitCheck(NO_ERROR), mIndex(-1)
 {
     width  = w;
     height = h;
@@ -111,6 +111,9 @@
     if (mOwner != ownData)
         return INVALID_OPERATION;
 
+    if (handle && w==width && h==height && f==format && reqUsage==usage)
+        return NO_ERROR;
+
     if (handle) {
         GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
         allocator.free(handle);
@@ -122,9 +125,6 @@
 status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
         uint32_t reqUsage)
 {
-    if (format == PIXEL_FORMAT_RGBX_8888)
-        format = PIXEL_FORMAT_RGBA_8888;
-
     GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
     status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
     if (err == NO_ERROR) {
@@ -132,7 +132,6 @@
         this->height = h;
         this->format = format;
         this->usage  = reqUsage;
-        mVStride = 0;
     }
     return err;
 }
@@ -173,7 +172,6 @@
         sur->height = height;
         sur->stride = stride;
         sur->format = format;
-        sur->vstride = mVStride;
         sur->data = static_cast<GGLubyte*>(vaddr);
     }
     return res;
@@ -267,14 +265,6 @@
     return mIndex;
 }
 
-void GraphicBuffer::setVerticalStride(uint32_t vstride) {
-    mVStride = vstride;
-}
-
-uint32_t GraphicBuffer::getVerticalStride() const {
-    return mVStride;
-}
-
 // ---------------------------------------------------------------------------
 
 }; // namespace android
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 6ae7e74..d51664d 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -15,6 +15,8 @@
 ** limitations under the License.
 */
 
+#define LOG_TAG "GraphicBufferAllocator"
+
 #include <cutils/log.h>
 
 #include <utils/Singleton.h>
@@ -61,9 +63,9 @@
     const size_t c = list.size();
     for (size_t i=0 ; i<c ; i++) {
         const alloc_rec_t& rec(list.valueAt(i));
-        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u x %4u | %2d | 0x%08x\n",
+        snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
             list.keyAt(i), rec.size/1024.0f, 
-            rec.w, rec.h, rec.format, rec.usage);
+            rec.w, rec.s, rec.h, rec.format, rec.usage);
         result.append(buffer);
         total += rec.size;
     }
@@ -71,16 +73,13 @@
     result.append(buffer);
 }
 
-static inline uint32_t clamp(uint32_t c) {
-    return c>0 ? c : 1;
-}
-
 status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
         int usage, buffer_handle_t* handle, int32_t* stride)
 {
-    // make sure to not allocate a 0 x 0 buffer
-    w = clamp(w);
-    h = clamp(h);
+    // make sure to not allocate a N x 0 or 0 x N buffer, since this is
+    // allowed from an API stand-point allocate a 1x1 buffer instead.
+    if (!w || !h)
+        w = h = 1;
 
     // we have a h/w allocator and h/w buffer is requested
     status_t err; 
@@ -100,9 +99,9 @@
         alloc_rec_t rec;
         rec.w = w;
         rec.h = h;
+        rec.s = *stride;
         rec.format = format;
         rec.usage = usage;
-        rec.vaddr = 0;
         rec.size = h * stride[0] * bytesPerPixel(format);
         list.add(*handle, rec);
     } else {
diff --git a/libs/ui/Input.cpp b/libs/ui/Input.cpp
new file mode 100644
index 0000000..811edaf
--- /dev/null
+++ b/libs/ui/Input.cpp
@@ -0,0 +1,215 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// Provides a pipe-based transport for native events in the NDK.
+//
+#define LOG_TAG "Input"
+
+//#define LOG_NDEBUG 0
+
+#include <ui/Input.h>
+
+namespace android {
+
+// class InputEvent
+
+void InputEvent::initialize(int32_t deviceId, int32_t source) {
+    mDeviceId = deviceId;
+    mSource = source;
+}
+
+void InputEvent::initialize(const InputEvent& from) {
+    mDeviceId = from.mDeviceId;
+    mSource = from.mSource;
+}
+
+// class KeyEvent
+
+bool KeyEvent::hasDefaultAction(int32_t keyCode) {
+    switch (keyCode) {
+        case AKEYCODE_HOME:
+        case AKEYCODE_BACK:
+        case AKEYCODE_CALL:
+        case AKEYCODE_ENDCALL:
+        case AKEYCODE_VOLUME_UP:
+        case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_POWER:
+        case AKEYCODE_CAMERA:
+        case AKEYCODE_HEADSETHOOK:
+        case AKEYCODE_MENU:
+        case AKEYCODE_NOTIFICATION:
+        case AKEYCODE_FOCUS:
+        case AKEYCODE_SEARCH:
+        case AKEYCODE_MEDIA_PLAY_PAUSE:
+        case AKEYCODE_MEDIA_STOP:
+        case AKEYCODE_MEDIA_NEXT:
+        case AKEYCODE_MEDIA_PREVIOUS:
+        case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_FAST_FORWARD:
+        case AKEYCODE_MUTE:
+            return true;
+    }
+    
+    return false;
+}
+
+bool KeyEvent::hasDefaultAction() const {
+    return hasDefaultAction(getKeyCode());
+}
+
+bool KeyEvent::isSystemKey(int32_t keyCode) {
+    switch (keyCode) {
+        case AKEYCODE_MENU:
+        case AKEYCODE_SOFT_RIGHT:
+        case AKEYCODE_HOME:
+        case AKEYCODE_BACK:
+        case AKEYCODE_CALL:
+        case AKEYCODE_ENDCALL:
+        case AKEYCODE_VOLUME_UP:
+        case AKEYCODE_VOLUME_DOWN:
+        case AKEYCODE_MUTE:
+        case AKEYCODE_POWER:
+        case AKEYCODE_HEADSETHOOK:
+        case AKEYCODE_MEDIA_PLAY_PAUSE:
+        case AKEYCODE_MEDIA_STOP:
+        case AKEYCODE_MEDIA_NEXT:
+        case AKEYCODE_MEDIA_PREVIOUS:
+        case AKEYCODE_MEDIA_REWIND:
+        case AKEYCODE_MEDIA_FAST_FORWARD:
+        case AKEYCODE_CAMERA:
+        case AKEYCODE_FOCUS:
+        case AKEYCODE_SEARCH:
+            return true;
+    }
+    
+    return false;
+}
+
+bool KeyEvent::isSystemKey() const {
+    return isSystemKey(getKeyCode());
+}
+
+void KeyEvent::initialize(
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t keyCode,
+        int32_t scanCode,
+        int32_t metaState,
+        int32_t repeatCount,
+        nsecs_t downTime,
+        nsecs_t eventTime) {
+    InputEvent::initialize(deviceId, source);
+    mAction = action;
+    mFlags = flags;
+    mKeyCode = keyCode;
+    mScanCode = scanCode;
+    mMetaState = metaState;
+    mRepeatCount = repeatCount;
+    mDownTime = downTime;
+    mEventTime = eventTime;
+}
+
+void KeyEvent::initialize(const KeyEvent& from) {
+    InputEvent::initialize(from);
+    mAction = from.mAction;
+    mFlags = from.mFlags;
+    mKeyCode = from.mKeyCode;
+    mScanCode = from.mScanCode;
+    mMetaState = from.mMetaState;
+    mRepeatCount = from.mRepeatCount;
+    mDownTime = from.mDownTime;
+    mEventTime = from.mEventTime;
+}
+
+// class MotionEvent
+
+void MotionEvent::initialize(
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t edgeFlags,
+        int32_t metaState,
+        float xOffset,
+        float yOffset,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const int32_t* pointerIds,
+        const PointerCoords* pointerCoords) {
+    InputEvent::initialize(deviceId, source);
+    mAction = action;
+    mFlags = flags;
+    mEdgeFlags = edgeFlags;
+    mMetaState = metaState;
+    mXOffset = xOffset;
+    mYOffset = yOffset;
+    mXPrecision = xPrecision;
+    mYPrecision = yPrecision;
+    mDownTime = downTime;
+    mPointerIds.clear();
+    mPointerIds.appendArray(pointerIds, pointerCount);
+    mSampleEventTimes.clear();
+    mSamplePointerCoords.clear();
+    addSample(eventTime, pointerCoords);
+}
+
+void MotionEvent::addSample(
+        int64_t eventTime,
+        const PointerCoords* pointerCoords) {
+    mSampleEventTimes.push(eventTime);
+    mSamplePointerCoords.appendArray(pointerCoords, getPointerCount());
+}
+
+void MotionEvent::offsetLocation(float xOffset, float yOffset) {
+    mXOffset += xOffset;
+    mYOffset += yOffset;
+}
+
+// class InputDeviceInfo
+
+InputDeviceInfo::InputDeviceInfo() {
+    initialize(-1, String8("uninitialized device info"));
+}
+
+InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) :
+        mId(other.mId), mName(other.mName), mSources(other.mSources),
+        mKeyboardType(other.mKeyboardType),
+        mMotionRanges(other.mMotionRanges) {
+}
+
+InputDeviceInfo::~InputDeviceInfo() {
+}
+
+void InputDeviceInfo::initialize(int32_t id, const String8& name) {
+    mId = id;
+    mName = name;
+    mSources = 0;
+    mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE;
+    mMotionRanges.clear();
+}
+
+const InputDeviceInfo::MotionRange* InputDeviceInfo::getMotionRange(int32_t rangeType) const {
+    ssize_t index = mMotionRanges.indexOfKey(rangeType);
+    return index >= 0 ? & mMotionRanges.valueAt(index) : NULL;
+}
+
+void InputDeviceInfo::addSource(uint32_t source) {
+    mSources |= source;
+}
+
+void InputDeviceInfo::addMotionRange(int32_t rangeType, float min, float max,
+        float flat, float fuzz) {
+    MotionRange range = { min, max, flat, fuzz };
+    addMotionRange(rangeType, range);
+}
+
+void InputDeviceInfo::addMotionRange(int32_t rangeType, const MotionRange& range) {
+    mMotionRanges.add(rangeType, range);
+}
+
+} // namespace android
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
new file mode 100644
index 0000000..df232d4
--- /dev/null
+++ b/libs/ui/InputDispatcher.cpp
@@ -0,0 +1,1874 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input dispatcher.
+//
+#define LOG_TAG "InputDispatcher"
+
+//#define LOG_NDEBUG 0
+
+// Log detailed debug messages about each inbound event notification to the dispatcher.
+#define DEBUG_INBOUND_EVENT_DETAILS 0
+
+// Log detailed debug messages about each outbound event processed by the dispatcher.
+#define DEBUG_OUTBOUND_EVENT_DETAILS 0
+
+// Log debug messages about batching.
+#define DEBUG_BATCHING 0
+
+// Log debug messages about the dispatch cycle.
+#define DEBUG_DISPATCH_CYCLE 0
+
+// Log debug messages about registrations.
+#define DEBUG_REGISTRATION 0
+
+// Log debug messages about performance statistics.
+#define DEBUG_PERFORMANCE_STATISTICS 0
+
+// Log debug messages about input event injection.
+#define DEBUG_INJECTION 0
+
+// Log debug messages about input event throttling.
+#define DEBUG_THROTTLING 0
+
+#include <cutils/log.h>
+#include <ui/InputDispatcher.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+namespace android {
+
+// TODO, this needs to be somewhere else, perhaps in the policy
+static inline bool isMovementKey(int32_t keyCode) {
+    return keyCode == AKEYCODE_DPAD_UP
+            || keyCode == AKEYCODE_DPAD_DOWN
+            || keyCode == AKEYCODE_DPAD_LEFT
+            || keyCode == AKEYCODE_DPAD_RIGHT;
+}
+
+static inline nsecs_t now() {
+    return systemTime(SYSTEM_TIME_MONOTONIC);
+}
+
+// --- InputDispatcher ---
+
+InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
+    mPolicy(policy) {
+    mPollLoop = new PollLoop(false);
+
+    mInboundQueue.head.refCount = -1;
+    mInboundQueue.head.type = EventEntry::TYPE_SENTINEL;
+    mInboundQueue.head.eventTime = LONG_LONG_MIN;
+
+    mInboundQueue.tail.refCount = -1;
+    mInboundQueue.tail.type = EventEntry::TYPE_SENTINEL;
+    mInboundQueue.tail.eventTime = LONG_LONG_MAX;
+
+    mKeyRepeatState.lastKeyEntry = NULL;
+
+    int32_t maxEventsPerSecond = policy->getMaxEventsPerSecond();
+    mThrottleState.minTimeBetweenEvents = 1000000000LL / maxEventsPerSecond;
+    mThrottleState.lastDeviceId = -1;
+
+#if DEBUG_THROTTLING
+    mThrottleState.originalSampleCount = 0;
+    LOGD("Throttling - Max events per second = %d", maxEventsPerSecond);
+#endif
+
+    mCurrentInputTargetsValid = false;
+}
+
+InputDispatcher::~InputDispatcher() {
+    resetKeyRepeatLocked();
+
+    while (mConnectionsByReceiveFd.size() != 0) {
+        unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
+    }
+
+    for (EventEntry* entry = mInboundQueue.head.next; entry != & mInboundQueue.tail; ) {
+        EventEntry* next = entry->next;
+        mAllocator.releaseEventEntry(next);
+        entry = next;
+    }
+}
+
+void InputDispatcher::dispatchOnce() {
+    nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
+    nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
+
+    bool skipPoll = false;
+    nsecs_t currentTime;
+    nsecs_t nextWakeupTime = LONG_LONG_MAX;
+    { // acquire lock
+        AutoMutex _l(mLock);
+        currentTime = now();
+
+        // Reset the key repeat timer whenever we disallow key events, even if the next event
+        // is not a key.  This is to ensure that we abort a key repeat if the device is just coming
+        // out of sleep.
+        // XXX we should handle resetting input state coming out of sleep more generally elsewhere
+        if (keyRepeatTimeout < 0) {
+            resetKeyRepeatLocked();
+        }
+
+        // Detect and process timeouts for all connections and determine if there are any
+        // synchronous event dispatches pending.  This step is entirely non-interruptible.
+        bool hasPendingSyncTarget = false;
+        size_t activeConnectionCount = mActiveConnections.size();
+        for (size_t i = 0; i < activeConnectionCount; i++) {
+            Connection* connection = mActiveConnections.itemAt(i);
+
+            if (connection->hasPendingSyncTarget()) {
+                hasPendingSyncTarget = true;
+            }
+
+            nsecs_t connectionTimeoutTime  = connection->nextTimeoutTime;
+            if (connectionTimeoutTime <= currentTime) {
+                mTimedOutConnections.add(connection);
+            } else if (connectionTimeoutTime < nextWakeupTime) {
+                nextWakeupTime = connectionTimeoutTime;
+            }
+        }
+
+        size_t timedOutConnectionCount = mTimedOutConnections.size();
+        for (size_t i = 0; i < timedOutConnectionCount; i++) {
+            Connection* connection = mTimedOutConnections.itemAt(i);
+            timeoutDispatchCycleLocked(currentTime, connection);
+            skipPoll = true;
+        }
+        mTimedOutConnections.clear();
+
+        // If we don't have a pending sync target, then we can begin delivering a new event.
+        // (Otherwise we wait for dispatch to complete for that target.)
+        if (! hasPendingSyncTarget) {
+            if (mInboundQueue.isEmpty()) {
+                if (mKeyRepeatState.lastKeyEntry) {
+                    if (currentTime >= mKeyRepeatState.nextRepeatTime) {
+                        processKeyRepeatLockedInterruptible(currentTime, keyRepeatDelay);
+                        skipPoll = true;
+                    } else {
+                        if (mKeyRepeatState.nextRepeatTime < nextWakeupTime) {
+                            nextWakeupTime = mKeyRepeatState.nextRepeatTime;
+                        }
+                    }
+                }
+            } else {
+                // Inbound queue has at least one entry.
+                EventEntry* entry = mInboundQueue.head.next;
+
+                // Consider throttling the entry if it is a move event and there are no
+                // other events behind it in the queue.  Due to movement batching, additional
+                // samples may be appended to this event by the time the throttling timeout
+                // expires.
+                // TODO Make this smarter and consider throttling per device independently.
+                if (entry->type == EventEntry::TYPE_MOTION) {
+                    MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+                    int32_t deviceId = motionEntry->deviceId;
+                    uint32_t source = motionEntry->source;
+                    if (motionEntry->next == & mInboundQueue.tail
+                            && motionEntry->action == AMOTION_EVENT_ACTION_MOVE
+                            && deviceId == mThrottleState.lastDeviceId
+                            && source == mThrottleState.lastSource) {
+                        nsecs_t nextTime = mThrottleState.lastEventTime
+                                + mThrottleState.minTimeBetweenEvents;
+                        if (currentTime < nextTime) {
+                            // Throttle it!
+#if DEBUG_THROTTLING
+                            LOGD("Throttling - Delaying motion event for "
+                                    "device 0x%x, source 0x%08x by up to %0.3fms.",
+                                    deviceId, source, (nextTime - currentTime) * 0.000001);
+#endif
+                            if (nextTime < nextWakeupTime) {
+                                nextWakeupTime = nextTime;
+                            }
+                            if (mThrottleState.originalSampleCount == 0) {
+                                mThrottleState.originalSampleCount =
+                                        motionEntry->countSamples();
+                            }
+                            goto Throttle;
+                        }
+                    }
+
+#if DEBUG_THROTTLING
+                    if (mThrottleState.originalSampleCount != 0) {
+                        uint32_t count = motionEntry->countSamples();
+                        LOGD("Throttling - Motion event sample count grew by %d from %d to %d.",
+                                count - mThrottleState.originalSampleCount,
+                                mThrottleState.originalSampleCount, count);
+                        mThrottleState.originalSampleCount = 0;
+                    }
+#endif
+
+                    mThrottleState.lastEventTime = entry->eventTime < currentTime
+                            ? entry->eventTime : currentTime;
+                    mThrottleState.lastDeviceId = deviceId;
+                    mThrottleState.lastSource = source;
+                }
+
+                // Start processing the entry but leave it on the queue until later so that the
+                // input reader can keep appending samples onto a motion event between the
+                // time we started processing it and the time we finally enqueue dispatch
+                // entries for it.
+                switch (entry->type) {
+                case EventEntry::TYPE_CONFIGURATION_CHANGED: {
+                    ConfigurationChangedEntry* typedEntry =
+                            static_cast<ConfigurationChangedEntry*>(entry);
+                    processConfigurationChangedLockedInterruptible(currentTime, typedEntry);
+                    break;
+                }
+
+                case EventEntry::TYPE_KEY: {
+                    KeyEntry* typedEntry = static_cast<KeyEntry*>(entry);
+                    processKeyLockedInterruptible(currentTime, typedEntry, keyRepeatTimeout);
+                    break;
+                }
+
+                case EventEntry::TYPE_MOTION: {
+                    MotionEntry* typedEntry = static_cast<MotionEntry*>(entry);
+                    processMotionLockedInterruptible(currentTime, typedEntry);
+                    break;
+                }
+
+                default:
+                    assert(false);
+                    break;
+                }
+
+                // Dequeue and release the event entry that we just processed.
+                mInboundQueue.dequeue(entry);
+                mAllocator.releaseEventEntry(entry);
+                skipPoll = true;
+
+            Throttle: ;
+            }
+        }
+
+        // Run any deferred commands.
+        skipPoll |= runCommandsLockedInterruptible();
+    } // release lock
+
+    // If we dispatched anything, don't poll just now.  Wait for the next iteration.
+    // Contents may have shifted during flight.
+    if (skipPoll) {
+        return;
+    }
+
+    // Wait for callback or timeout or wake.  (make sure we round up, not down)
+    nsecs_t timeout = (nextWakeupTime - currentTime + 999999LL) / 1000000LL;
+    int32_t timeoutMillis = timeout > INT_MAX ? -1 : timeout > 0 ? int32_t(timeout) : 0;
+    mPollLoop->pollOnce(timeoutMillis);
+}
+
+bool InputDispatcher::runCommandsLockedInterruptible() {
+    if (mCommandQueue.isEmpty()) {
+        return false;
+    }
+
+    do {
+        CommandEntry* commandEntry = mCommandQueue.dequeueAtHead();
+
+        Command command = commandEntry->command;
+        (this->*command)(commandEntry); // commands are implicitly 'LockedInterruptible'
+
+        commandEntry->connection.clear();
+        mAllocator.releaseCommandEntry(commandEntry);
+    } while (! mCommandQueue.isEmpty());
+    return true;
+}
+
+InputDispatcher::CommandEntry* InputDispatcher::postCommandLocked(Command command) {
+    CommandEntry* commandEntry = mAllocator.obtainCommandEntry(command);
+    mCommandQueue.enqueueAtTail(commandEntry);
+    return commandEntry;
+}
+
+void InputDispatcher::processConfigurationChangedLockedInterruptible(
+        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processConfigurationChanged - eventTime=%lld", entry->eventTime);
+#endif
+
+    // Reset key repeating in case a keyboard device was added or removed or something.
+    resetKeyRepeatLocked();
+
+    mLock.unlock();
+
+    mPolicy->notifyConfigurationChanged(entry->eventTime);
+
+    mLock.lock();
+}
+
+void InputDispatcher::processKeyLockedInterruptible(
+        nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
+            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
+            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags, entry->action,
+            entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
+            entry->downTime);
+#endif
+
+    if (entry->action == AKEY_EVENT_ACTION_DOWN && ! entry->isInjected()) {
+        if (mKeyRepeatState.lastKeyEntry
+                && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
+            // We have seen two identical key downs in a row which indicates that the device
+            // driver is automatically generating key repeats itself.  We take note of the
+            // repeat here, but we disable our own next key repeat timer since it is clear that
+            // we will not need to synthesize key repeats ourselves.
+            entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
+            resetKeyRepeatLocked();
+            mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
+        } else {
+            // Not a repeat.  Save key down state in case we do see a repeat later.
+            resetKeyRepeatLocked();
+            mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
+        }
+        mKeyRepeatState.lastKeyEntry = entry;
+        entry->refCount += 1;
+    } else {
+        resetKeyRepeatLocked();
+    }
+
+    identifyInputTargetsAndDispatchKeyLockedInterruptible(currentTime, entry);
+}
+
+void InputDispatcher::processKeyRepeatLockedInterruptible(
+        nsecs_t currentTime, nsecs_t keyRepeatDelay) {
+    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
+
+    // Search the inbound queue for a key up corresponding to this device.
+    // It doesn't make sense to generate a key repeat event if the key is already up.
+    for (EventEntry* queuedEntry = mInboundQueue.head.next;
+            queuedEntry != & mInboundQueue.tail; queuedEntry = entry->next) {
+        if (queuedEntry->type == EventEntry::TYPE_KEY) {
+            KeyEntry* queuedKeyEntry = static_cast<KeyEntry*>(queuedEntry);
+            if (queuedKeyEntry->deviceId == entry->deviceId
+                    && entry->action == AKEY_EVENT_ACTION_UP) {
+                resetKeyRepeatLocked();
+                return;
+            }
+        }
+    }
+
+    // Synthesize a key repeat.
+    // Reuse the repeated key entry if it is otherwise unreferenced.
+    uint32_t policyFlags = entry->policyFlags & POLICY_FLAG_RAW_MASK;
+    if (entry->refCount == 1) {
+        entry->eventTime = currentTime;
+        entry->policyFlags = policyFlags;
+        entry->repeatCount += 1;
+    } else {
+        KeyEntry* newEntry = mAllocator.obtainKeyEntry(currentTime,
+                entry->deviceId, entry->source, policyFlags,
+                entry->action, entry->flags, entry->keyCode, entry->scanCode,
+                entry->metaState, entry->repeatCount + 1, entry->downTime);
+
+        mKeyRepeatState.lastKeyEntry = newEntry;
+        mAllocator.releaseKeyEntry(entry);
+
+        entry = newEntry;
+    }
+
+    if (entry->repeatCount == 1) {
+        entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
+    }
+
+    mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
+
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processKeyRepeat - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
+            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
+            "repeatCount=%d, downTime=%lld",
+            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
+            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
+            entry->repeatCount, entry->downTime);
+#endif
+
+    identifyInputTargetsAndDispatchKeyLockedInterruptible(currentTime, entry);
+}
+
+void InputDispatcher::processMotionLockedInterruptible(
+        nsecs_t currentTime, MotionEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("processMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
+            "action=0x%x, flags=0x%x, "
+            "metaState=0x%x, edgeFlags=0x%x, xPrecision=%f, yPrecision=%f, downTime=%lld",
+            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
+            entry->action, entry->flags,
+            entry->metaState, entry->edgeFlags, entry->xPrecision, entry->yPrecision,
+            entry->downTime);
+
+    // Print the most recent sample that we have available, this may change due to batching.
+    size_t sampleCount = 1;
+    MotionSample* sample = & entry->firstSample;
+    for (; sample->next != NULL; sample = sample->next) {
+        sampleCount += 1;
+    }
+    for (uint32_t i = 0; i < entry->pointerCount; i++) {
+        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
+                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
+                "orientation=%f",
+                i, entry->pointerIds[i],
+                sample->pointerCoords[i].x, sample->pointerCoords[i].y,
+                sample->pointerCoords[i].pressure, sample->pointerCoords[i].size,
+                sample->pointerCoords[i].touchMajor, sample->pointerCoords[i].touchMinor,
+                sample->pointerCoords[i].toolMajor, sample->pointerCoords[i].toolMinor,
+                sample->pointerCoords[i].orientation);
+    }
+
+    // Keep in mind that due to batching, it is possible for the number of samples actually
+    // dispatched to change before the application finally consumed them.
+    if (entry->action == AMOTION_EVENT_ACTION_MOVE) {
+        LOGD("  ... Total movement samples currently batched %d ...", sampleCount);
+    }
+#endif
+
+    identifyInputTargetsAndDispatchMotionLockedInterruptible(currentTime, entry);
+}
+
+void InputDispatcher::identifyInputTargetsAndDispatchKeyLockedInterruptible(
+        nsecs_t currentTime, KeyEntry* entry) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("identifyInputTargetsAndDispatchKey");
+#endif
+
+    entry->dispatchInProgress = true;
+    mCurrentInputTargetsValid = false;
+    mLock.unlock();
+
+    mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
+            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
+            entry->downTime, entry->eventTime);
+
+    mCurrentInputTargets.clear();
+    int32_t injectionResult = mPolicy->waitForKeyEventTargets(& mReusableKeyEvent,
+            entry->policyFlags, entry->injectorPid, entry->injectorUid,
+            mCurrentInputTargets);
+
+    mLock.lock();
+    mCurrentInputTargetsValid = true;
+
+    setInjectionResultLocked(entry, injectionResult);
+
+    if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) {
+        dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+    }
+}
+
+void InputDispatcher::identifyInputTargetsAndDispatchMotionLockedInterruptible(
+        nsecs_t currentTime, MotionEntry* entry) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("identifyInputTargetsAndDispatchMotion");
+#endif
+
+    entry->dispatchInProgress = true;
+    mCurrentInputTargetsValid = false;
+    mLock.unlock();
+
+    mReusableMotionEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
+            entry->edgeFlags, entry->metaState,
+            0, 0, entry->xPrecision, entry->yPrecision,
+            entry->downTime, entry->eventTime, entry->pointerCount, entry->pointerIds,
+            entry->firstSample.pointerCoords);
+
+    mCurrentInputTargets.clear();
+    int32_t injectionResult = mPolicy->waitForMotionEventTargets(& mReusableMotionEvent,
+            entry->policyFlags, entry->injectorPid, entry->injectorUid,
+            mCurrentInputTargets);
+
+    mLock.lock();
+    mCurrentInputTargetsValid = true;
+
+    setInjectionResultLocked(entry, injectionResult);
+
+    if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED) {
+        dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+    }
+}
+
+void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
+        EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("dispatchEventToCurrentInputTargets - "
+            "resumeWithAppendedMotionSample=%s",
+            resumeWithAppendedMotionSample ? "true" : "false");
+#endif
+
+    assert(eventEntry->dispatchInProgress); // should already have been set to true
+
+    for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
+        const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
+
+        ssize_t connectionIndex = getConnectionIndex(inputTarget.inputChannel);
+        if (connectionIndex >= 0) {
+            sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+            prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
+                    resumeWithAppendedMotionSample);
+        } else {
+            LOGW("Framework requested delivery of an input event to channel '%s' but it "
+                    "is not registered with the input dispatcher.",
+                    inputTarget.inputChannel->getName().string());
+        }
+    }
+}
+
+void InputDispatcher::prepareDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, EventEntry* eventEntry, const InputTarget* inputTarget,
+        bool resumeWithAppendedMotionSample) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ prepareDispatchCycle - flags=%d, timeout=%lldns, "
+            "xOffset=%f, yOffset=%f, resumeWithAppendedMotionSample=%s",
+            connection->getInputChannelName(), inputTarget->flags, inputTarget->timeout,
+            inputTarget->xOffset, inputTarget->yOffset,
+            resumeWithAppendedMotionSample ? "true" : "false");
+#endif
+
+    // Skip this event if the connection status is not normal.
+    // We don't want to queue outbound events at all if the connection is broken or
+    // not responding.
+    if (connection->status != Connection::STATUS_NORMAL) {
+        LOGV("channel '%s' ~ Dropping event because the channel status is %s",
+                connection->getStatusLabel());
+        return;
+    }
+
+    // Resume the dispatch cycle with a freshly appended motion sample.
+    // First we check that the last dispatch entry in the outbound queue is for the same
+    // motion event to which we appended the motion sample.  If we find such a dispatch
+    // entry, and if it is currently in progress then we try to stream the new sample.
+    bool wasEmpty = connection->outboundQueue.isEmpty();
+
+    if (! wasEmpty && resumeWithAppendedMotionSample) {
+        DispatchEntry* motionEventDispatchEntry =
+                connection->findQueuedDispatchEntryForEvent(eventEntry);
+        if (motionEventDispatchEntry) {
+            // If the dispatch entry is not in progress, then we must be busy dispatching an
+            // earlier event.  Not a problem, the motion event is on the outbound queue and will
+            // be dispatched later.
+            if (! motionEventDispatchEntry->inProgress) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Not streaming because the motion event has "
+                        "not yet been dispatched.  "
+                        "(Waiting for earlier events to be consumed.)",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+            // If the dispatch entry is in progress but it already has a tail of pending
+            // motion samples, then it must mean that the shared memory buffer filled up.
+            // Not a problem, when this dispatch cycle is finished, we will eventually start
+            // a new dispatch cycle to process the tail and that tail includes the newly
+            // appended motion sample.
+            if (motionEventDispatchEntry->tailMotionSample) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Not streaming because no new samples can "
+                        "be appended to the motion event in this dispatch cycle.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+            // The dispatch entry is in progress and is still potentially open for streaming.
+            // Try to stream the new motion sample.  This might fail if the consumer has already
+            // consumed the motion event (or if the channel is broken).
+            MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
+            status_t status = connection->inputPublisher.appendMotionSample(
+                    appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
+            if (status == OK) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Successfully streamed new motion sample.",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+#if DEBUG_BATCHING
+            if (status == NO_MEMORY) {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event because the shared memory buffer is full.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+            } else if (status == status_t(FAILED_TRANSACTION)) {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event because the event has already been consumed.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+            } else {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event due to an error, status=%d.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName(), status);
+            }
+#endif
+            // Failed to stream.  Start a new tail of pending motion samples to dispatch
+            // in the next cycle.
+            motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
+            return;
+        }
+    }
+
+    // This is a new event.
+    // Enqueue a new dispatch entry onto the outbound queue for this connection.
+    DispatchEntry* dispatchEntry = mAllocator.obtainDispatchEntry(eventEntry); // increments ref
+    dispatchEntry->targetFlags = inputTarget->flags;
+    dispatchEntry->xOffset = inputTarget->xOffset;
+    dispatchEntry->yOffset = inputTarget->yOffset;
+    dispatchEntry->timeout = inputTarget->timeout;
+    dispatchEntry->inProgress = false;
+    dispatchEntry->headMotionSample = NULL;
+    dispatchEntry->tailMotionSample = NULL;
+
+    if (dispatchEntry->isSyncTarget()) {
+        eventEntry->pendingSyncDispatches += 1;
+    }
+
+    // Handle the case where we could not stream a new motion sample because the consumer has
+    // already consumed the motion event (otherwise the corresponding dispatch entry would
+    // still be in the outbound queue for this connection).  We set the head motion sample
+    // to the list starting with the newly appended motion sample.
+    if (resumeWithAppendedMotionSample) {
+#if DEBUG_BATCHING
+        LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
+                "that cannot be streamed because the motion event has already been consumed.",
+                connection->getInputChannelName());
+#endif
+        MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
+        dispatchEntry->headMotionSample = appendedMotionSample;
+    }
+
+    // Enqueue the dispatch entry.
+    connection->outboundQueue.enqueueAtTail(dispatchEntry);
+
+    // If the outbound queue was previously empty, start the dispatch cycle going.
+    if (wasEmpty) {
+        activateConnectionLocked(connection.get());
+        startDispatchCycleLocked(currentTime, connection);
+    }
+}
+
+void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ startDispatchCycle",
+            connection->getInputChannelName());
+#endif
+
+    assert(connection->status == Connection::STATUS_NORMAL);
+    assert(! connection->outboundQueue.isEmpty());
+
+    DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
+    assert(! dispatchEntry->inProgress);
+
+    // TODO throttle successive ACTION_MOVE motion events for the same device
+    //      possible implementation could set a brief poll timeout here and resume starting the
+    //      dispatch cycle when elapsed
+
+    // Publish the event.
+    status_t status;
+    switch (dispatchEntry->eventEntry->type) {
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
+
+        // Apply target flags.
+        int32_t action = keyEntry->action;
+        int32_t flags = keyEntry->flags;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
+            flags |= AKEY_EVENT_FLAG_CANCELED;
+        }
+
+        // Publish the key event.
+        status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
+                action, flags, keyEntry->keyCode, keyEntry->scanCode,
+                keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
+                keyEntry->eventTime);
+
+        if (status) {
+            LOGE("channel '%s' ~ Could not publish key event, "
+                    "status=%d", connection->getInputChannelName(), status);
+            abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            return;
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
+
+        // Apply target flags.
+        int32_t action = motionEntry->action;
+        int32_t flags = motionEntry->flags;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
+            action = AMOTION_EVENT_ACTION_OUTSIDE;
+        }
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
+            action = AMOTION_EVENT_ACTION_CANCEL;
+        }
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
+            flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+        }
+
+        // If headMotionSample is non-NULL, then it points to the first new sample that we
+        // were unable to dispatch during the previous cycle so we resume dispatching from
+        // that point in the list of motion samples.
+        // Otherwise, we just start from the first sample of the motion event.
+        MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
+        if (! firstMotionSample) {
+            firstMotionSample = & motionEntry->firstSample;
+        }
+
+        // Set the X and Y offset depending on the input source.
+        float xOffset, yOffset;
+        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+            xOffset = dispatchEntry->xOffset;
+            yOffset = dispatchEntry->yOffset;
+        } else {
+            xOffset = 0.0f;
+            yOffset = 0.0f;
+        }
+
+        // Publish the motion event and the first motion sample.
+        status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
+                motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
+                xOffset, yOffset,
+                motionEntry->xPrecision, motionEntry->yPrecision,
+                motionEntry->downTime, firstMotionSample->eventTime,
+                motionEntry->pointerCount, motionEntry->pointerIds,
+                firstMotionSample->pointerCoords);
+
+        if (status) {
+            LOGE("channel '%s' ~ Could not publish motion event, "
+                    "status=%d", connection->getInputChannelName(), status);
+            abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            return;
+        }
+
+        // Append additional motion samples.
+        MotionSample* nextMotionSample = firstMotionSample->next;
+        for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
+            status = connection->inputPublisher.appendMotionSample(
+                    nextMotionSample->eventTime, nextMotionSample->pointerCoords);
+            if (status == NO_MEMORY) {
+#if DEBUG_DISPATCH_CYCLE
+                    LOGD("channel '%s' ~ Shared memory buffer full.  Some motion samples will "
+                            "be sent in the next dispatch cycle.",
+                            connection->getInputChannelName());
+#endif
+                break;
+            }
+            if (status != OK) {
+                LOGE("channel '%s' ~ Could not append motion sample "
+                        "for a reason other than out of memory, status=%d",
+                        connection->getInputChannelName(), status);
+                abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+                return;
+            }
+        }
+
+        // Remember the next motion sample that we could not dispatch, in case we ran out
+        // of space in the shared memory buffer.
+        dispatchEntry->tailMotionSample = nextMotionSample;
+        break;
+    }
+
+    default: {
+        assert(false);
+    }
+    }
+
+    // Send the dispatch signal.
+    status = connection->inputPublisher.sendDispatchSignal();
+    if (status) {
+        LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
+                connection->getInputChannelName(), status);
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+        return;
+    }
+
+    // Record information about the newly started dispatch cycle.
+    dispatchEntry->inProgress = true;
+
+    connection->lastEventTime = dispatchEntry->eventEntry->eventTime;
+    connection->lastDispatchTime = currentTime;
+
+    nsecs_t timeout = dispatchEntry->timeout;
+    connection->setNextTimeoutTime(currentTime, timeout);
+
+    // Notify other system components.
+    onDispatchCycleStartedLocked(currentTime, connection);
+}
+
+void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ finishDispatchCycle - %01.1fms since event, "
+            "%01.1fms since dispatch",
+            connection->getInputChannelName(),
+            connection->getEventLatencyMillis(currentTime),
+            connection->getDispatchLatencyMillis(currentTime));
+#endif
+
+    if (connection->status == Connection::STATUS_BROKEN
+            || connection->status == Connection::STATUS_ZOMBIE) {
+        return;
+    }
+
+    // Clear the pending timeout.
+    connection->nextTimeoutTime = LONG_LONG_MAX;
+
+    if (connection->status == Connection::STATUS_NOT_RESPONDING) {
+        // Recovering from an ANR.
+        connection->status = Connection::STATUS_NORMAL;
+
+        // Notify other system components.
+        onDispatchCycleFinishedLocked(currentTime, connection, true /*recoveredFromANR*/);
+    } else {
+        // Normal finish.  Not much to do here.
+
+        // Notify other system components.
+        onDispatchCycleFinishedLocked(currentTime, connection, false /*recoveredFromANR*/);
+    }
+
+    // Reset the publisher since the event has been consumed.
+    // We do this now so that the publisher can release some of its internal resources
+    // while waiting for the next dispatch cycle to begin.
+    status_t status = connection->inputPublisher.reset();
+    if (status) {
+        LOGE("channel '%s' ~ Could not reset publisher, status=%d",
+                connection->getInputChannelName(), status);
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+        return;
+    }
+
+    // Start the next dispatch cycle for this connection.
+    while (! connection->outboundQueue.isEmpty()) {
+        DispatchEntry* dispatchEntry = connection->outboundQueue.head.next;
+        if (dispatchEntry->inProgress) {
+             // Finish or resume current event in progress.
+            if (dispatchEntry->tailMotionSample) {
+                // We have a tail of undispatched motion samples.
+                // Reuse the same DispatchEntry and start a new cycle.
+                dispatchEntry->inProgress = false;
+                dispatchEntry->headMotionSample = dispatchEntry->tailMotionSample;
+                dispatchEntry->tailMotionSample = NULL;
+                startDispatchCycleLocked(currentTime, connection);
+                return;
+            }
+            // Finished.
+            connection->outboundQueue.dequeueAtHead();
+            if (dispatchEntry->isSyncTarget()) {
+                decrementPendingSyncDispatchesLocked(dispatchEntry->eventEntry);
+            }
+            mAllocator.releaseDispatchEntry(dispatchEntry);
+        } else {
+            // If the head is not in progress, then we must have already dequeued the in
+            // progress event, which means we actually aborted it (due to ANR).
+            // So just start the next event for this connection.
+            startDispatchCycleLocked(currentTime, connection);
+            return;
+        }
+    }
+
+    // Outbound queue is empty, deactivate the connection.
+    deactivateConnectionLocked(connection.get());
+}
+
+void InputDispatcher::timeoutDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ timeoutDispatchCycle",
+            connection->getInputChannelName());
+#endif
+
+    if (connection->status != Connection::STATUS_NORMAL) {
+        return;
+    }
+
+    // Enter the not responding state.
+    connection->status = Connection::STATUS_NOT_RESPONDING;
+    connection->lastANRTime = currentTime;
+
+    // Notify other system components.
+    // This enqueues a command which will eventually either call
+    // resumeAfterTimeoutDispatchCycleLocked or abortDispatchCycleLocked.
+    onDispatchCycleANRLocked(currentTime, connection);
+}
+
+void InputDispatcher::resumeAfterTimeoutDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, nsecs_t newTimeout) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ resumeAfterTimeoutDispatchCycleLocked",
+            connection->getInputChannelName());
+#endif
+
+    if (connection->status != Connection::STATUS_NOT_RESPONDING) {
+        return;
+    }
+
+    // Resume normal dispatch.
+    connection->status = Connection::STATUS_NORMAL;
+    connection->setNextTimeoutTime(currentTime, newTimeout);
+}
+
+void InputDispatcher::abortDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, bool broken) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
+            connection->getInputChannelName(), broken ? "true" : "false");
+#endif
+
+    // Clear the pending timeout.
+    connection->nextTimeoutTime = LONG_LONG_MAX;
+
+    // Clear the outbound queue.
+    if (! connection->outboundQueue.isEmpty()) {
+        do {
+            DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
+            if (dispatchEntry->isSyncTarget()) {
+                decrementPendingSyncDispatchesLocked(dispatchEntry->eventEntry);
+            }
+            mAllocator.releaseDispatchEntry(dispatchEntry);
+        } while (! connection->outboundQueue.isEmpty());
+
+        deactivateConnectionLocked(connection.get());
+    }
+
+    // Handle the case where the connection appears to be unrecoverably broken.
+    // Ignore already broken or zombie connections.
+    if (broken) {
+        if (connection->status == Connection::STATUS_NORMAL
+                || connection->status == Connection::STATUS_NOT_RESPONDING) {
+            connection->status = Connection::STATUS_BROKEN;
+
+            // Notify other system components.
+            onDispatchCycleBrokenLocked(currentTime, connection);
+        }
+    }
+}
+
+bool InputDispatcher::handleReceiveCallback(int receiveFd, int events, void* data) {
+    InputDispatcher* d = static_cast<InputDispatcher*>(data);
+
+    { // acquire lock
+        AutoMutex _l(d->mLock);
+
+        ssize_t connectionIndex = d->mConnectionsByReceiveFd.indexOfKey(receiveFd);
+        if (connectionIndex < 0) {
+            LOGE("Received spurious receive callback for unknown input channel.  "
+                    "fd=%d, events=0x%x", receiveFd, events);
+            return false; // remove the callback
+        }
+
+        nsecs_t currentTime = now();
+
+        sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
+        if (events & (POLLERR | POLLHUP | POLLNVAL)) {
+            LOGE("channel '%s' ~ Consumer closed input channel or an error occurred.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            d->runCommandsLockedInterruptible();
+            return false; // remove the callback
+        }
+
+        if (! (events & POLLIN)) {
+            LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            return true;
+        }
+
+        status_t status = connection->inputPublisher.receiveFinishedSignal();
+        if (status) {
+            LOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
+                    connection->getInputChannelName(), status);
+            d->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            d->runCommandsLockedInterruptible();
+            return false; // remove the callback
+        }
+
+        d->finishDispatchCycleLocked(currentTime, connection);
+        d->runCommandsLockedInterruptible();
+        return true;
+    } // release lock
+}
+
+void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
+#endif
+
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(newEntry);
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+}
+
+void InputDispatcher::notifyAppSwitchComing(nsecs_t eventTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyAppSwitchComing - eventTime=%lld", eventTime);
+#endif
+
+    // Remove movement keys from the queue from most recent to least recent, stopping at the
+    // first non-movement key.
+    // TODO: Include a detailed description of why we do this...
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        for (EventEntry* entry = mInboundQueue.tail.prev; entry != & mInboundQueue.head; ) {
+            EventEntry* prev = entry->prev;
+
+            if (entry->type == EventEntry::TYPE_KEY) {
+                KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
+                if (isMovementKey(keyEntry->keyCode)) {
+                    LOGV("Dropping movement key during app switch: keyCode=%d, action=%d",
+                            keyEntry->keyCode, keyEntry->action);
+                    mInboundQueue.dequeue(keyEntry);
+
+                    setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+
+                    mAllocator.releaseKeyEntry(keyEntry);
+                } else {
+                    // stop at last non-movement key
+                    break;
+                }
+            }
+
+            entry = prev;
+        }
+    } // release lock
+}
+
+void InputDispatcher::notifyKey(nsecs_t eventTime, int32_t deviceId, int32_t source,
+        uint32_t policyFlags, int32_t action, int32_t flags,
+        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyKey - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, action=0x%x, "
+            "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%lld",
+            eventTime, deviceId, source, policyFlags, action, flags,
+            keyCode, scanCode, metaState, downTime);
+#endif
+
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        int32_t repeatCount = 0;
+        KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
+                deviceId, source, policyFlags, action, flags, keyCode, scanCode,
+                metaState, repeatCount, downTime);
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(newEntry);
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+}
+
+void InputDispatcher::notifyMotion(nsecs_t eventTime, int32_t deviceId, int32_t source,
+        uint32_t policyFlags, int32_t action, int32_t flags, int32_t metaState, int32_t edgeFlags,
+        uint32_t pointerCount, const int32_t* pointerIds, const PointerCoords* pointerCoords,
+        float xPrecision, float yPrecision, nsecs_t downTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyMotion - eventTime=%lld, deviceId=0x%x, source=0x%x, policyFlags=0x%x, "
+            "action=0x%x, flags=0x%x, metaState=0x%x, edgeFlags=0x%x, "
+            "xPrecision=%f, yPrecision=%f, downTime=%lld",
+            eventTime, deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
+            xPrecision, yPrecision, downTime);
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        LOGD("  Pointer %d: id=%d, x=%f, y=%f, pressure=%f, size=%f, "
+                "touchMajor=%f, touchMinor=%f, toolMajor=%f, toolMinor=%f, "
+                "orientation=%f",
+                i, pointerIds[i], pointerCoords[i].x, pointerCoords[i].y,
+                pointerCoords[i].pressure, pointerCoords[i].size,
+                pointerCoords[i].touchMajor, pointerCoords[i].touchMinor,
+                pointerCoords[i].toolMajor, pointerCoords[i].toolMinor,
+                pointerCoords[i].orientation);
+    }
+#endif
+
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Attempt batching and streaming of move events.
+        if (action == AMOTION_EVENT_ACTION_MOVE) {
+            // BATCHING CASE
+            //
+            // Try to append a move sample to the tail of the inbound queue for this device.
+            // Give up if we encounter a non-move motion event for this device since that
+            // means we cannot append any new samples until a new motion event has started.
+            for (EventEntry* entry = mInboundQueue.tail.prev;
+                    entry != & mInboundQueue.head; entry = entry->prev) {
+                if (entry->type != EventEntry::TYPE_MOTION) {
+                    // Keep looking for motion events.
+                    continue;
+                }
+
+                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+                if (motionEntry->deviceId != deviceId) {
+                    // Keep looking for this device.
+                    continue;
+                }
+
+                if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+                        || motionEntry->pointerCount != pointerCount
+                        || motionEntry->isInjected()) {
+                    // Last motion event in the queue for this device is not compatible for
+                    // appending new samples.  Stop here.
+                    goto NoBatchingOrStreaming;
+                }
+
+                // The last motion event is a move and is compatible for appending.
+                // Do the batching magic.
+                mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
+#if DEBUG_BATCHING
+                LOGD("Appended motion sample onto batch for most recent "
+                        "motion event for this device in the inbound queue.");
+#endif
+
+                // Sanity check for special case because dispatch is interruptible.
+                // The dispatch logic is partially interruptible and releases its lock while
+                // identifying targets.  However, as soon as the targets have been identified,
+                // the dispatcher proceeds to write a dispatch entry into all relevant outbound
+                // queues and then promptly removes the motion entry from the queue.
+                //
+                // Consequently, we should never observe the case where the inbound queue contains
+                // an in-progress motion entry unless the current input targets are invalid
+                // (currently being computed).  Check for this!
+                assert(! (motionEntry->dispatchInProgress && mCurrentInputTargetsValid));
+
+                return; // done!
+            }
+
+            // STREAMING CASE
+            //
+            // There is no pending motion event (of any kind) for this device in the inbound queue.
+            // Search the outbound queues for a synchronously dispatched motion event for this
+            // device.  If found, then we append the new sample to that event and then try to
+            // push it out to all current targets.  It is possible that some targets will already
+            // have consumed the motion event.  This case is automatically handled by the
+            // logic in prepareDispatchCycleLocked by tracking where resumption takes place.
+            //
+            // The reason we look for a synchronously dispatched motion event is because we
+            // want to be sure that no other motion events have been dispatched since the move.
+            // It's also convenient because it means that the input targets are still valid.
+            // This code could be improved to support streaming of asynchronously dispatched
+            // motion events (which might be significantly more efficient) but it may become
+            // a little more complicated as a result.
+            //
+            // Note: This code crucially depends on the invariant that an outbound queue always
+            //       contains at most one synchronous event and it is always last (but it might
+            //       not be first!).
+            if (mCurrentInputTargetsValid) {
+                for (size_t i = 0; i < mActiveConnections.size(); i++) {
+                    Connection* connection = mActiveConnections.itemAt(i);
+                    if (! connection->outboundQueue.isEmpty()) {
+                        DispatchEntry* dispatchEntry = connection->outboundQueue.tail.prev;
+                        if (dispatchEntry->isSyncTarget()) {
+                            if (dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION) {
+                                goto NoBatchingOrStreaming;
+                            }
+
+                            MotionEntry* syncedMotionEntry = static_cast<MotionEntry*>(
+                                    dispatchEntry->eventEntry);
+                            if (syncedMotionEntry->action != AMOTION_EVENT_ACTION_MOVE
+                                    || syncedMotionEntry->deviceId != deviceId
+                                    || syncedMotionEntry->pointerCount != pointerCount
+                                    || syncedMotionEntry->isInjected()) {
+                                goto NoBatchingOrStreaming;
+                            }
+
+                            // Found synced move entry.  Append sample and resume dispatch.
+                            mAllocator.appendMotionSample(syncedMotionEntry, eventTime,
+                                    pointerCoords);
+    #if DEBUG_BATCHING
+                            LOGD("Appended motion sample onto batch for most recent synchronously "
+                                    "dispatched motion event for this device in the outbound queues.");
+    #endif
+                            nsecs_t currentTime = now();
+                            dispatchEventToCurrentInputTargetsLocked(currentTime, syncedMotionEntry,
+                                    true /*resumeWithAppendedMotionSample*/);
+
+                            runCommandsLockedInterruptible();
+                            return; // done!
+                        }
+                    }
+                }
+            }
+
+NoBatchingOrStreaming:;
+        }
+
+        // Just enqueue a new motion event.
+        MotionEntry* newEntry = mAllocator.obtainMotionEntry(eventTime,
+                deviceId, source, policyFlags, action, flags, metaState, edgeFlags,
+                xPrecision, yPrecision, downTime,
+                pointerCount, pointerIds, pointerCoords);
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(newEntry);
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+}
+
+int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
+        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
+            "syncMode=%d, timeoutMillis=%d",
+            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
+#endif
+
+    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
+
+    EventEntry* injectedEntry;
+    bool wasEmpty;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        injectedEntry = createEntryFromInputEventLocked(event);
+        injectedEntry->refCount += 1;
+        injectedEntry->injectorPid = injectorPid;
+        injectedEntry->injectorUid = injectorUid;
+
+        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+            injectedEntry->injectionIsAsync = true;
+        }
+
+        wasEmpty = mInboundQueue.isEmpty();
+        mInboundQueue.enqueueAtTail(injectedEntry);
+
+    } // release lock
+
+    if (wasEmpty) {
+        mPollLoop->wake();
+    }
+
+    int32_t injectionResult;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+        } else {
+            for (;;) {
+                injectionResult = injectedEntry->injectionResult;
+                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
+                    break;
+                }
+
+                nsecs_t remainingTimeout = endTime - now();
+                if (remainingTimeout <= 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Timed out waiting for injection result "
+                            "to become available.");
+#endif
+                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+                    break;
+                }
+
+                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
+            }
+
+            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
+                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
+                while (injectedEntry->pendingSyncDispatches != 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Waiting for %d pending synchronous dispatches.",
+                            injectedEntry->pendingSyncDispatches);
+#endif
+                    nsecs_t remainingTimeout = endTime - now();
+                    if (remainingTimeout <= 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Timed out waiting for pending synchronous "
+                            "dispatches to finish.");
+#endif
+                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+                        break;
+                    }
+
+                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
+                }
+            }
+        }
+
+        mAllocator.releaseEventEntry(injectedEntry);
+    } // release lock
+
+#if DEBUG_INJECTION
+    LOGD("injectInputEvent - Finished with result %d.  "
+            "injectorPid=%d, injectorUid=%d",
+            injectionResult, injectorPid, injectorUid);
+#endif
+
+    return injectionResult;
+}
+
+void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
+    if (entry->isInjected()) {
+#if DEBUG_INJECTION
+        LOGD("Setting input event injection result to %d.  "
+                "injectorPid=%d, injectorUid=%d",
+                 injectionResult, entry->injectorPid, entry->injectorUid);
+#endif
+
+        if (entry->injectionIsAsync) {
+            // Log the outcome since the injector did not wait for the injection result.
+            switch (injectionResult) {
+            case INPUT_EVENT_INJECTION_SUCCEEDED:
+                LOGV("Asynchronous input event injection succeeded.");
+                break;
+            case INPUT_EVENT_INJECTION_FAILED:
+                LOGW("Asynchronous input event injection failed.");
+                break;
+            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+                LOGW("Asynchronous input event injection permission denied.");
+                break;
+            case INPUT_EVENT_INJECTION_TIMED_OUT:
+                LOGW("Asynchronous input event injection timed out.");
+                break;
+            }
+        }
+
+        entry->injectionResult = injectionResult;
+        mInjectionResultAvailableCondition.broadcast();
+    }
+}
+
+void InputDispatcher::decrementPendingSyncDispatchesLocked(EventEntry* entry) {
+    entry->pendingSyncDispatches -= 1;
+
+    if (entry->isInjected() && entry->pendingSyncDispatches == 0) {
+        mInjectionSyncFinishedCondition.broadcast();
+    }
+}
+
+InputDispatcher::EventEntry* InputDispatcher::createEntryFromInputEventLocked(
+        const InputEvent* event) {
+    switch (event->getType()) {
+    case AINPUT_EVENT_TYPE_KEY: {
+        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
+        uint32_t policyFlags = POLICY_FLAG_INJECTED;
+
+        KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
+                keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
+                keyEvent->getAction(), keyEvent->getFlags(),
+                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
+                keyEvent->getRepeatCount(), keyEvent->getDownTime());
+        return keyEntry;
+    }
+
+    case AINPUT_EVENT_TYPE_MOTION: {
+        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+        uint32_t policyFlags = POLICY_FLAG_INJECTED;
+
+        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
+        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
+        size_t pointerCount = motionEvent->getPointerCount();
+
+        MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
+                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                motionEvent->getAction(), motionEvent->getFlags(),
+                motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
+                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
+                motionEvent->getDownTime(), uint32_t(pointerCount),
+                motionEvent->getPointerIds(), samplePointerCoords);
+        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
+            sampleEventTimes += 1;
+            samplePointerCoords += pointerCount;
+            mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
+        }
+        return motionEntry;
+    }
+
+    default:
+        assert(false);
+        return NULL;
+    }
+}
+
+void InputDispatcher::resetKeyRepeatLocked() {
+    if (mKeyRepeatState.lastKeyEntry) {
+        mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
+        mKeyRepeatState.lastKeyEntry = NULL;
+    }
+}
+
+void InputDispatcher::preemptInputDispatch() {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("preemptInputDispatch");
+#endif
+
+    bool preemptedOne = false;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        for (size_t i = 0; i < mActiveConnections.size(); i++) {
+            Connection* connection = mActiveConnections[i];
+            if (connection->hasPendingSyncTarget()) {
+#if DEBUG_DISPATCH_CYCLE
+                LOGD("channel '%s' ~ Preempted pending synchronous dispatch",
+                        connection->getInputChannelName());
+#endif
+                connection->outboundQueue.tail.prev->targetFlags &= ~ InputTarget::FLAG_SYNC;
+                preemptedOne = true;
+            }
+        }
+    } // release lock
+
+    if (preemptedOne) {
+        // Wake up the poll loop so it can get a head start dispatching the next event.
+        mPollLoop->wake();
+    }
+}
+
+status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel) {
+#if DEBUG_REGISTRATION
+    LOGD("channel '%s' ~ registerInputChannel", inputChannel->getName().string());
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (getConnectionIndex(inputChannel) >= 0) {
+            LOGW("Attempted to register already registered input channel '%s'",
+                    inputChannel->getName().string());
+            return BAD_VALUE;
+        }
+
+        sp<Connection> connection = new Connection(inputChannel);
+        status_t status = connection->initialize();
+        if (status) {
+            LOGE("Failed to initialize input publisher for input channel '%s', status=%d",
+                    inputChannel->getName().string(), status);
+            return status;
+        }
+
+        int32_t receiveFd = inputChannel->getReceivePipeFd();
+        mConnectionsByReceiveFd.add(receiveFd, connection);
+
+        mPollLoop->setCallback(receiveFd, POLLIN, handleReceiveCallback, this);
+
+        runCommandsLockedInterruptible();
+    } // release lock
+    return OK;
+}
+
+status_t InputDispatcher::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
+#if DEBUG_REGISTRATION
+    LOGD("channel '%s' ~ unregisterInputChannel", inputChannel->getName().string());
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ssize_t connectionIndex = getConnectionIndex(inputChannel);
+        if (connectionIndex < 0) {
+            LOGW("Attempted to unregister already unregistered input channel '%s'",
+                    inputChannel->getName().string());
+            return BAD_VALUE;
+        }
+
+        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+        mConnectionsByReceiveFd.removeItemsAt(connectionIndex);
+
+        connection->status = Connection::STATUS_ZOMBIE;
+
+        mPollLoop->removeCallback(inputChannel->getReceivePipeFd());
+
+        nsecs_t currentTime = now();
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+
+        runCommandsLockedInterruptible();
+    } // release lock
+
+    // Wake the poll loop because removing the connection may have changed the current
+    // synchronization state.
+    mPollLoop->wake();
+    return OK;
+}
+
+ssize_t InputDispatcher::getConnectionIndex(const sp<InputChannel>& inputChannel) {
+    ssize_t connectionIndex = mConnectionsByReceiveFd.indexOfKey(inputChannel->getReceivePipeFd());
+    if (connectionIndex >= 0) {
+        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+        if (connection->inputChannel.get() == inputChannel.get()) {
+            return connectionIndex;
+        }
+    }
+
+    return -1;
+}
+
+void InputDispatcher::activateConnectionLocked(Connection* connection) {
+    for (size_t i = 0; i < mActiveConnections.size(); i++) {
+        if (mActiveConnections.itemAt(i) == connection) {
+            return;
+        }
+    }
+    mActiveConnections.add(connection);
+}
+
+void InputDispatcher::deactivateConnectionLocked(Connection* connection) {
+    for (size_t i = 0; i < mActiveConnections.size(); i++) {
+        if (mActiveConnections.itemAt(i) == connection) {
+            mActiveConnections.removeAt(i);
+            return;
+        }
+    }
+}
+
+void InputDispatcher::onDispatchCycleStartedLocked(
+        nsecs_t currentTime, const sp<Connection>& connection) {
+}
+
+void InputDispatcher::onDispatchCycleFinishedLocked(
+        nsecs_t currentTime, const sp<Connection>& connection, bool recoveredFromANR) {
+    if (recoveredFromANR) {
+        LOGI("channel '%s' ~ Recovered from ANR.  %01.1fms since event, "
+                "%01.1fms since dispatch, %01.1fms since ANR",
+                connection->getInputChannelName(),
+                connection->getEventLatencyMillis(currentTime),
+                connection->getDispatchLatencyMillis(currentTime),
+                connection->getANRLatencyMillis(currentTime));
+
+        CommandEntry* commandEntry = postCommandLocked(
+                & InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible);
+        commandEntry->connection = connection;
+    }
+}
+
+void InputDispatcher::onDispatchCycleANRLocked(
+        nsecs_t currentTime, const sp<Connection>& connection) {
+    LOGI("channel '%s' ~ Not responding!  %01.1fms since event, %01.1fms since dispatch",
+            connection->getInputChannelName(),
+            connection->getEventLatencyMillis(currentTime),
+            connection->getDispatchLatencyMillis(currentTime));
+
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doNotifyInputChannelANRLockedInterruptible);
+    commandEntry->connection = connection;
+}
+
+void InputDispatcher::onDispatchCycleBrokenLocked(
+        nsecs_t currentTime, const sp<Connection>& connection) {
+    LOGE("channel '%s' ~ Channel is unrecoverably broken and will be disposed!",
+            connection->getInputChannelName());
+
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible);
+    commandEntry->connection = connection;
+}
+
+void InputDispatcher::doNotifyInputChannelBrokenLockedInterruptible(
+        CommandEntry* commandEntry) {
+    sp<Connection> connection = commandEntry->connection;
+
+    if (connection->status != Connection::STATUS_ZOMBIE) {
+        mLock.unlock();
+
+        mPolicy->notifyInputChannelBroken(connection->inputChannel);
+
+        mLock.lock();
+    }
+}
+
+void InputDispatcher::doNotifyInputChannelANRLockedInterruptible(
+        CommandEntry* commandEntry) {
+    sp<Connection> connection = commandEntry->connection;
+
+    if (connection->status != Connection::STATUS_ZOMBIE) {
+        mLock.unlock();
+
+        nsecs_t newTimeout;
+        bool resume = mPolicy->notifyInputChannelANR(connection->inputChannel, newTimeout);
+
+        mLock.lock();
+
+        nsecs_t currentTime = now();
+        if (resume) {
+            resumeAfterTimeoutDispatchCycleLocked(currentTime, connection, newTimeout);
+        } else {
+            abortDispatchCycleLocked(currentTime, connection, false /*(not) broken*/);
+        }
+    }
+}
+
+void InputDispatcher::doNotifyInputChannelRecoveredFromANRLockedInterruptible(
+        CommandEntry* commandEntry) {
+    sp<Connection> connection = commandEntry->connection;
+
+    if (connection->status != Connection::STATUS_ZOMBIE) {
+        mLock.unlock();
+
+        mPolicy->notifyInputChannelRecoveredFromANR(connection->inputChannel);
+
+        mLock.lock();
+    }
+}
+
+
+// --- InputDispatcher::Allocator ---
+
+InputDispatcher::Allocator::Allocator() {
+}
+
+void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
+        nsecs_t eventTime) {
+    entry->type = type;
+    entry->refCount = 1;
+    entry->dispatchInProgress = false;
+    entry->eventTime = eventTime;
+    entry->injectionResult = INPUT_EVENT_INJECTION_PENDING;
+    entry->injectionIsAsync = false;
+    entry->injectorPid = -1;
+    entry->injectorUid = -1;
+    entry->pendingSyncDispatches = 0;
+}
+
+InputDispatcher::ConfigurationChangedEntry*
+InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
+    ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
+    initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
+    return entry;
+}
+
+InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
+        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+        int32_t repeatCount, nsecs_t downTime) {
+    KeyEntry* entry = mKeyEntryPool.alloc();
+    initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
+
+    entry->deviceId = deviceId;
+    entry->source = source;
+    entry->policyFlags = policyFlags;
+    entry->action = action;
+    entry->flags = flags;
+    entry->keyCode = keyCode;
+    entry->scanCode = scanCode;
+    entry->metaState = metaState;
+    entry->repeatCount = repeatCount;
+    entry->downTime = downTime;
+    return entry;
+}
+
+InputDispatcher::MotionEntry* InputDispatcher::Allocator::obtainMotionEntry(nsecs_t eventTime,
+        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action, int32_t flags,
+        int32_t metaState, int32_t edgeFlags, float xPrecision, float yPrecision,
+        nsecs_t downTime, uint32_t pointerCount,
+        const int32_t* pointerIds, const PointerCoords* pointerCoords) {
+    MotionEntry* entry = mMotionEntryPool.alloc();
+    initializeEventEntry(entry, EventEntry::TYPE_MOTION, eventTime);
+
+    entry->eventTime = eventTime;
+    entry->deviceId = deviceId;
+    entry->source = source;
+    entry->policyFlags = policyFlags;
+    entry->action = action;
+    entry->flags = flags;
+    entry->metaState = metaState;
+    entry->edgeFlags = edgeFlags;
+    entry->xPrecision = xPrecision;
+    entry->yPrecision = yPrecision;
+    entry->downTime = downTime;
+    entry->pointerCount = pointerCount;
+    entry->firstSample.eventTime = eventTime;
+    entry->firstSample.next = NULL;
+    entry->lastSample = & entry->firstSample;
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        entry->pointerIds[i] = pointerIds[i];
+        entry->firstSample.pointerCoords[i] = pointerCoords[i];
+    }
+    return entry;
+}
+
+InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
+        EventEntry* eventEntry) {
+    DispatchEntry* entry = mDispatchEntryPool.alloc();
+    entry->eventEntry = eventEntry;
+    eventEntry->refCount += 1;
+    return entry;
+}
+
+InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
+    CommandEntry* entry = mCommandEntryPool.alloc();
+    entry->command = command;
+    return entry;
+}
+
+void InputDispatcher::Allocator::releaseEventEntry(EventEntry* entry) {
+    switch (entry->type) {
+    case EventEntry::TYPE_CONFIGURATION_CHANGED:
+        releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
+        break;
+    case EventEntry::TYPE_KEY:
+        releaseKeyEntry(static_cast<KeyEntry*>(entry));
+        break;
+    case EventEntry::TYPE_MOTION:
+        releaseMotionEntry(static_cast<MotionEntry*>(entry));
+        break;
+    default:
+        assert(false);
+        break;
+    }
+}
+
+void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
+        ConfigurationChangedEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        mConfigurationChangeEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        mKeyEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
+            MotionSample* next = sample->next;
+            mMotionSamplePool.free(sample);
+            sample = next;
+        }
+        mMotionEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
+    releaseEventEntry(entry->eventEntry);
+    mDispatchEntryPool.free(entry);
+}
+
+void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
+    mCommandEntryPool.free(entry);
+}
+
+void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
+        nsecs_t eventTime, const PointerCoords* pointerCoords) {
+    MotionSample* sample = mMotionSamplePool.alloc();
+    sample->eventTime = eventTime;
+    uint32_t pointerCount = motionEntry->pointerCount;
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        sample->pointerCoords[i] = pointerCoords[i];
+    }
+
+    sample->next = NULL;
+    motionEntry->lastSample->next = sample;
+    motionEntry->lastSample = sample;
+}
+
+// --- InputDispatcher::MotionEntry ---
+
+uint32_t InputDispatcher::MotionEntry::countSamples() const {
+    uint32_t count = 1;
+    for (MotionSample* sample = firstSample.next; sample != NULL; sample = sample->next) {
+        count += 1;
+    }
+    return count;
+}
+
+// --- InputDispatcher::Connection ---
+
+InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
+        status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
+        nextTimeoutTime(LONG_LONG_MAX),
+        lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX),
+        lastANRTime(LONG_LONG_MAX) {
+}
+
+InputDispatcher::Connection::~Connection() {
+}
+
+status_t InputDispatcher::Connection::initialize() {
+    return inputPublisher.initialize();
+}
+
+void InputDispatcher::Connection::setNextTimeoutTime(nsecs_t currentTime, nsecs_t timeout) {
+    nextTimeoutTime = (timeout >= 0) ? currentTime + timeout : LONG_LONG_MAX;
+}
+
+const char* InputDispatcher::Connection::getStatusLabel() const {
+    switch (status) {
+    case STATUS_NORMAL:
+        return "NORMAL";
+
+    case STATUS_BROKEN:
+        return "BROKEN";
+
+    case STATUS_NOT_RESPONDING:
+        return "NOT_RESPONDING";
+
+    case STATUS_ZOMBIE:
+        return "ZOMBIE";
+
+    default:
+        return "UNKNOWN";
+    }
+}
+
+InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
+        const EventEntry* eventEntry) const {
+    for (DispatchEntry* dispatchEntry = outboundQueue.tail.prev;
+            dispatchEntry != & outboundQueue.head; dispatchEntry = dispatchEntry->prev) {
+        if (dispatchEntry->eventEntry == eventEntry) {
+            return dispatchEntry;
+        }
+    }
+    return NULL;
+}
+
+// --- InputDispatcher::CommandEntry ---
+
+InputDispatcher::CommandEntry::CommandEntry() {
+}
+
+InputDispatcher::CommandEntry::~CommandEntry() {
+}
+
+
+// --- InputDispatcherThread ---
+
+InputDispatcherThread::InputDispatcherThread(const sp<InputDispatcherInterface>& dispatcher) :
+        Thread(/*canCallJava*/ true), mDispatcher(dispatcher) {
+}
+
+InputDispatcherThread::~InputDispatcherThread() {
+}
+
+bool InputDispatcherThread::threadLoop() {
+    mDispatcher->dispatchOnce();
+    return true;
+}
+
+} // namespace android
diff --git a/libs/ui/InputManager.cpp b/libs/ui/InputManager.cpp
new file mode 100644
index 0000000..ed4f07b
--- /dev/null
+++ b/libs/ui/InputManager.cpp
@@ -0,0 +1,123 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input manager.
+//
+#define LOG_TAG "InputManager"
+
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <ui/InputManager.h>
+#include <ui/InputReader.h>
+#include <ui/InputDispatcher.h>
+
+namespace android {
+
+InputManager::InputManager(
+        const sp<EventHubInterface>& eventHub,
+        const sp<InputReaderPolicyInterface>& readerPolicy,
+        const sp<InputDispatcherPolicyInterface>& dispatcherPolicy) {
+    mDispatcher = new InputDispatcher(dispatcherPolicy);
+    mReader = new InputReader(eventHub, readerPolicy, mDispatcher);
+    initialize();
+}
+
+InputManager::InputManager(
+        const sp<InputReaderInterface>& reader,
+        const sp<InputDispatcherInterface>& dispatcher) :
+        mReader(reader),
+        mDispatcher(dispatcher) {
+    initialize();
+}
+
+InputManager::~InputManager() {
+    stop();
+}
+
+void InputManager::initialize() {
+    mReaderThread = new InputReaderThread(mReader);
+    mDispatcherThread = new InputDispatcherThread(mDispatcher);
+}
+
+status_t InputManager::start() {
+    status_t result = mDispatcherThread->run("InputDispatcher", PRIORITY_URGENT_DISPLAY);
+    if (result) {
+        LOGE("Could not start InputDispatcher thread due to error %d.", result);
+        return result;
+    }
+
+    result = mReaderThread->run("InputReader", PRIORITY_URGENT_DISPLAY);
+    if (result) {
+        LOGE("Could not start InputReader thread due to error %d.", result);
+
+        mDispatcherThread->requestExit();
+        return result;
+    }
+
+    return OK;
+}
+
+status_t InputManager::stop() {
+    status_t result = mReaderThread->requestExitAndWait();
+    if (result) {
+        LOGW("Could not stop InputReader thread due to error %d.", result);
+    }
+
+    result = mDispatcherThread->requestExitAndWait();
+    if (result) {
+        LOGW("Could not stop InputDispatcher thread due to error %d.", result);
+    }
+
+    return OK;
+}
+
+status_t InputManager::registerInputChannel(const sp<InputChannel>& inputChannel) {
+    return mDispatcher->registerInputChannel(inputChannel);
+}
+
+status_t InputManager::unregisterInputChannel(const sp<InputChannel>& inputChannel) {
+    return mDispatcher->unregisterInputChannel(inputChannel);
+}
+
+int32_t InputManager::injectInputEvent(const InputEvent* event,
+        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
+    return mDispatcher->injectInputEvent(event, injectorPid, injectorUid, syncMode, timeoutMillis);
+}
+
+void InputManager::preemptInputDispatch() {
+    mDispatcher->preemptInputDispatch();
+}
+
+void InputManager::getInputConfiguration(InputConfiguration* outConfiguration) {
+    mReader->getInputConfiguration(outConfiguration);
+}
+
+status_t InputManager::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
+    return mReader->getInputDeviceInfo(deviceId, outDeviceInfo);
+}
+
+void InputManager::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
+    mReader->getInputDeviceIds(outDeviceIds);
+}
+
+int32_t InputManager::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+        int32_t scanCode) {
+    return mReader->getScanCodeState(deviceId, sourceMask, scanCode);
+}
+
+int32_t InputManager::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+        int32_t keyCode) {
+    return mReader->getKeyCodeState(deviceId, sourceMask, keyCode);
+}
+
+int32_t InputManager::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t sw) {
+    return mReader->getSwitchState(deviceId, sourceMask, sw);
+}
+
+bool InputManager::hasKeys(int32_t deviceId, uint32_t sourceMask,
+        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+    return mReader->hasKeys(deviceId, sourceMask, numCodes, keyCodes, outFlags);
+}
+
+} // namespace android
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
new file mode 100644
index 0000000..d57b38c
--- /dev/null
+++ b/libs/ui/InputReader.cpp
@@ -0,0 +1,3312 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input reader.
+//
+#define LOG_TAG "InputReader"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages for each raw event received from the EventHub.
+#define DEBUG_RAW_EVENTS 0
+
+// Log debug messages about touch screen filtering hacks.
+#define DEBUG_HACKS 0
+
+// Log debug messages about virtual key processing.
+#define DEBUG_VIRTUAL_KEYS 0
+
+// Log debug messages about pointers.
+#define DEBUG_POINTERS 0
+
+// Log debug messages about pointer assignment calculations.
+#define DEBUG_POINTER_ASSIGNMENT 0
+
+#include <cutils/log.h>
+#include <ui/InputReader.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+
+#define INDENT "  "
+
+namespace android {
+
+// --- Static Functions ---
+
+template<typename T>
+inline static T abs(const T& value) {
+    return value < 0 ? - value : value;
+}
+
+template<typename T>
+inline static T min(const T& a, const T& b) {
+    return a < b ? a : b;
+}
+
+template<typename T>
+inline static void swap(T& a, T& b) {
+    T temp = a;
+    a = b;
+    b = temp;
+}
+
+inline static float avg(float x, float y) {
+    return (x + y) / 2;
+}
+
+inline static float pythag(float x, float y) {
+    return sqrtf(x * x + y * y);
+}
+
+
+int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
+    int32_t mask;
+    switch (keyCode) {
+    case AKEYCODE_ALT_LEFT:
+        mask = AMETA_ALT_LEFT_ON;
+        break;
+    case AKEYCODE_ALT_RIGHT:
+        mask = AMETA_ALT_RIGHT_ON;
+        break;
+    case AKEYCODE_SHIFT_LEFT:
+        mask = AMETA_SHIFT_LEFT_ON;
+        break;
+    case AKEYCODE_SHIFT_RIGHT:
+        mask = AMETA_SHIFT_RIGHT_ON;
+        break;
+    case AKEYCODE_SYM:
+        mask = AMETA_SYM_ON;
+        break;
+    default:
+        return oldMetaState;
+    }
+
+    int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask
+            & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON);
+
+    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
+        newMetaState |= AMETA_ALT_ON;
+    }
+
+    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
+        newMetaState |= AMETA_SHIFT_ON;
+    }
+
+    return newMetaState;
+}
+
+static const int32_t keyCodeRotationMap[][4] = {
+        // key codes enumerated counter-clockwise with the original (unrotated) key first
+        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
+        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
+        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
+        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
+        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
+};
+static const int keyCodeRotationMapSize =
+        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
+
+int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
+    if (orientation != InputReaderPolicyInterface::ROTATION_0) {
+        for (int i = 0; i < keyCodeRotationMapSize; i++) {
+            if (keyCode == keyCodeRotationMap[i][0]) {
+                return keyCodeRotationMap[i][orientation];
+            }
+        }
+    }
+    return keyCode;
+}
+
+static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
+    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
+}
+
+
+// --- InputDeviceCalibration ---
+
+InputDeviceCalibration::InputDeviceCalibration() {
+}
+
+void InputDeviceCalibration::clear() {
+    mProperties.clear();
+}
+
+void InputDeviceCalibration::addProperty(const String8& key, const String8& value) {
+    mProperties.add(key, value);
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const {
+    ssize_t index = mProperties.indexOfKey(key);
+    if (index < 0) {
+        return false;
+    }
+
+    outValue = mProperties.valueAt(index);
+    return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    int value = strtol(stringValue.string(), & end, 10);
+    if (*end != '\0') {
+        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected an integer.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    float value = strtof(stringValue.string(), & end);
+    if (*end != '\0') {
+        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected a float.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+
+// --- InputReader ---
+
+InputReader::InputReader(const sp<EventHubInterface>& eventHub,
+        const sp<InputReaderPolicyInterface>& policy,
+        const sp<InputDispatcherInterface>& dispatcher) :
+        mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+        mGlobalMetaState(0) {
+    configureExcludedDevices();
+    updateGlobalMetaState();
+    updateInputConfiguration();
+}
+
+InputReader::~InputReader() {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        delete mDevices.valueAt(i);
+    }
+}
+
+void InputReader::loopOnce() {
+    RawEvent rawEvent;
+    mEventHub->getEvent(& rawEvent);
+
+#if DEBUG_RAW_EVENTS
+    LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
+            rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
+            rawEvent.value);
+#endif
+
+    process(& rawEvent);
+}
+
+void InputReader::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EventHubInterface::DEVICE_ADDED:
+        addDevice(rawEvent->when, rawEvent->deviceId);
+        break;
+
+    case EventHubInterface::DEVICE_REMOVED:
+        removeDevice(rawEvent->when, rawEvent->deviceId);
+        break;
+
+    default:
+        consumeEvent(rawEvent);
+        break;
+    }
+}
+
+void InputReader::addDevice(nsecs_t when, int32_t deviceId) {
+    String8 name = mEventHub->getDeviceName(deviceId);
+    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+
+    // Write a log message about the added device as a heading for subsequent log messages.
+    LOGI("Device added: id=0x%x, name=%s", deviceId, name.string());
+
+    InputDevice* device = createDevice(deviceId, name, classes);
+    device->configure();
+
+    if (device->isIgnored()) {
+        LOGI(INDENT "Sources: none (device is ignored)");
+    } else {
+        LOGI(INDENT "Sources: 0x%08x", device->getSources());
+    }
+
+    bool added = false;
+    { // acquire device registry writer lock
+        RWLock::AutoWLock _wl(mDeviceRegistryLock);
+
+        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+        if (deviceIndex < 0) {
+            mDevices.add(deviceId, device);
+            added = true;
+        }
+    } // release device registry writer lock
+
+    if (! added) {
+        LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
+        delete device;
+        return;
+    }
+
+    handleConfigurationChanged(when);
+}
+
+void InputReader::removeDevice(nsecs_t when, int32_t deviceId) {
+    bool removed = false;
+    InputDevice* device = NULL;
+    { // acquire device registry writer lock
+        RWLock::AutoWLock _wl(mDeviceRegistryLock);
+
+        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+        if (deviceIndex >= 0) {
+            device = mDevices.valueAt(deviceIndex);
+            mDevices.removeItemsAt(deviceIndex, 1);
+            removed = true;
+        }
+    } // release device registry writer lock
+
+    if (! removed) {
+        LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
+        return;
+    }
+
+    // Write a log message about the removed device as a heading for subsequent log messages.
+    if (device->isIgnored()) {
+        LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)",
+                device->getId(), device->getName().string());
+    } else {
+        LOGI("Device removed: id=0x%x, name=%s, sources=%08x",
+                device->getId(), device->getName().string(), device->getSources());
+    }
+
+    device->reset();
+
+    delete device;
+
+    handleConfigurationChanged(when);
+}
+
+InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+    InputDevice* device = new InputDevice(this, deviceId, name);
+
+    const int32_t associatedDisplayId = 0; // FIXME: hardcoded for current single-display devices
+
+    // Switch-like devices.
+    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
+        device->addMapper(new SwitchInputMapper(device));
+    }
+
+    // Keyboard-like devices.
+    uint32_t keyboardSources = 0;
+    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
+    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
+        keyboardSources |= AINPUT_SOURCE_KEYBOARD;
+    }
+    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
+        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
+    }
+    if (classes & INPUT_DEVICE_CLASS_DPAD) {
+        keyboardSources |= AINPUT_SOURCE_DPAD;
+    }
+    if (classes & INPUT_DEVICE_CLASS_GAMEPAD) {
+        keyboardSources |= AINPUT_SOURCE_GAMEPAD;
+    }
+
+    if (keyboardSources != 0) {
+        device->addMapper(new KeyboardInputMapper(device,
+                associatedDisplayId, keyboardSources, keyboardType));
+    }
+
+    // Trackball-like devices.
+    if (classes & INPUT_DEVICE_CLASS_TRACKBALL) {
+        device->addMapper(new TrackballInputMapper(device, associatedDisplayId));
+    }
+
+    // Touchscreen-like devices.
+    if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN_MT) {
+        device->addMapper(new MultiTouchInputMapper(device, associatedDisplayId));
+    } else if (classes & INPUT_DEVICE_CLASS_TOUCHSCREEN) {
+        device->addMapper(new SingleTouchInputMapper(device, associatedDisplayId));
+    }
+
+    return device;
+}
+
+void InputReader::consumeEvent(const RawEvent* rawEvent) {
+    int32_t deviceId = rawEvent->deviceId;
+
+    { // acquire device registry reader lock
+        RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+        if (deviceIndex < 0) {
+            LOGW("Discarding event for unknown deviceId %d.", deviceId);
+            return;
+        }
+
+        InputDevice* device = mDevices.valueAt(deviceIndex);
+        if (device->isIgnored()) {
+            //LOGD("Discarding event for ignored deviceId %d.", deviceId);
+            return;
+        }
+
+        device->process(rawEvent);
+    } // release device registry reader lock
+}
+
+void InputReader::handleConfigurationChanged(nsecs_t when) {
+    // Reset global meta state because it depends on the list of all configured devices.
+    updateGlobalMetaState();
+
+    // Update input configuration.
+    updateInputConfiguration();
+
+    // Enqueue configuration changed.
+    mDispatcher->notifyConfigurationChanged(when);
+}
+
+void InputReader::configureExcludedDevices() {
+    Vector<String8> excludedDeviceNames;
+    mPolicy->getExcludedDeviceNames(excludedDeviceNames);
+
+    for (size_t i = 0; i < excludedDeviceNames.size(); i++) {
+        mEventHub->addExcludedDevice(excludedDeviceNames[i]);
+    }
+}
+
+void InputReader::updateGlobalMetaState() {
+    { // acquire state lock
+        AutoMutex _l(mStateLock);
+
+        mGlobalMetaState = 0;
+
+        { // acquire device registry reader lock
+            RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+            for (size_t i = 0; i < mDevices.size(); i++) {
+                InputDevice* device = mDevices.valueAt(i);
+                mGlobalMetaState |= device->getMetaState();
+            }
+        } // release device registry reader lock
+    } // release state lock
+}
+
+int32_t InputReader::getGlobalMetaState() {
+    { // acquire state lock
+        AutoMutex _l(mStateLock);
+
+        return mGlobalMetaState;
+    } // release state lock
+}
+
+void InputReader::updateInputConfiguration() {
+    { // acquire state lock
+        AutoMutex _l(mStateLock);
+
+        int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
+        int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
+        int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
+        { // acquire device registry reader lock
+            RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+            InputDeviceInfo deviceInfo;
+            for (size_t i = 0; i < mDevices.size(); i++) {
+                InputDevice* device = mDevices.valueAt(i);
+                device->getDeviceInfo(& deviceInfo);
+                uint32_t sources = deviceInfo.getSources();
+
+                if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
+                    touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
+                }
+                if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
+                    navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
+                } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
+                    navigationConfig = InputConfiguration::NAVIGATION_DPAD;
+                }
+                if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
+                    keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
+                }
+            }
+        } // release device registry reader lock
+
+        mInputConfiguration.touchScreen = touchScreenConfig;
+        mInputConfiguration.keyboard = keyboardConfig;
+        mInputConfiguration.navigation = navigationConfig;
+    } // release state lock
+}
+
+void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
+    { // acquire state lock
+        AutoMutex _l(mStateLock);
+
+        *outConfiguration = mInputConfiguration;
+    } // release state lock
+}
+
+status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
+    { // acquire device registry reader lock
+        RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+        if (deviceIndex < 0) {
+            return NAME_NOT_FOUND;
+        }
+
+        InputDevice* device = mDevices.valueAt(deviceIndex);
+        if (device->isIgnored()) {
+            return NAME_NOT_FOUND;
+        }
+
+        device->getDeviceInfo(outDeviceInfo);
+        return OK;
+    } // release device registy reader lock
+}
+
+void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
+    outDeviceIds.clear();
+
+    { // acquire device registry reader lock
+        RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+        size_t numDevices = mDevices.size();
+        for (size_t i = 0; i < numDevices; i++) {
+            InputDevice* device = mDevices.valueAt(i);
+            if (! device->isIgnored()) {
+                outDeviceIds.add(device->getId());
+            }
+        }
+    } // release device registy reader lock
+}
+
+int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
+        int32_t keyCode) {
+    return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
+}
+
+int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
+        int32_t scanCode) {
+    return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
+}
+
+int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
+    return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
+}
+
+int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+        GetStateFunc getStateFunc) {
+    { // acquire device registry reader lock
+        RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+        int32_t result = AKEY_STATE_UNKNOWN;
+        if (deviceId >= 0) {
+            ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+            if (deviceIndex >= 0) {
+                InputDevice* device = mDevices.valueAt(deviceIndex);
+                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+                    result = (device->*getStateFunc)(sourceMask, code);
+                }
+            }
+        } else {
+            size_t numDevices = mDevices.size();
+            for (size_t i = 0; i < numDevices; i++) {
+                InputDevice* device = mDevices.valueAt(i);
+                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+                    result = (device->*getStateFunc)(sourceMask, code);
+                    if (result >= AKEY_STATE_DOWN) {
+                        return result;
+                    }
+                }
+            }
+        }
+        return result;
+    } // release device registy reader lock
+}
+
+bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
+        size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+    memset(outFlags, 0, numCodes);
+    return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
+}
+
+bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    { // acquire device registry reader lock
+        RWLock::AutoRLock _rl(mDeviceRegistryLock);
+        bool result = false;
+        if (deviceId >= 0) {
+            ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+            if (deviceIndex >= 0) {
+                InputDevice* device = mDevices.valueAt(deviceIndex);
+                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+                    result = device->markSupportedKeyCodes(sourceMask,
+                            numCodes, keyCodes, outFlags);
+                }
+            }
+        } else {
+            size_t numDevices = mDevices.size();
+            for (size_t i = 0; i < numDevices; i++) {
+                InputDevice* device = mDevices.valueAt(i);
+                if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+                    result |= device->markSupportedKeyCodes(sourceMask,
+                            numCodes, keyCodes, outFlags);
+                }
+            }
+        }
+        return result;
+    } // release device registy reader lock
+}
+
+
+// --- InputReaderThread ---
+
+InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
+        Thread(/*canCallJava*/ true), mReader(reader) {
+}
+
+InputReaderThread::~InputReaderThread() {
+}
+
+bool InputReaderThread::threadLoop() {
+    mReader->loopOnce();
+    return true;
+}
+
+
+// --- InputDevice ---
+
+InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) :
+        mContext(context), mId(id), mName(name), mSources(0) {
+}
+
+InputDevice::~InputDevice() {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        delete mMappers[i];
+    }
+    mMappers.clear();
+}
+
+void InputDevice::addMapper(InputMapper* mapper) {
+    mMappers.add(mapper);
+}
+
+void InputDevice::configure() {
+    if (! isIgnored()) {
+        mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration);
+    }
+
+    mSources = 0;
+
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->configure();
+        mSources |= mapper->getSources();
+    }
+}
+
+void InputDevice::reset() {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->reset();
+    }
+}
+
+void InputDevice::process(const RawEvent* rawEvent) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->process(rawEvent);
+    }
+}
+
+void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
+    outDeviceInfo->initialize(mId, mName);
+
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->populateDeviceInfo(outDeviceInfo);
+    }
+}
+
+int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
+}
+
+int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
+}
+
+int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
+}
+
+int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
+    int32_t result = AKEY_STATE_UNKNOWN;
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
+            result = (mapper->*getStateFunc)(sourceMask, code);
+            if (result >= AKEY_STATE_DOWN) {
+                return result;
+            }
+        }
+    }
+    return result;
+}
+
+bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    bool result = false;
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
+            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
+        }
+    }
+    return result;
+}
+
+int32_t InputDevice::getMetaState() {
+    int32_t result = 0;
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        result |= mapper->getMetaState();
+    }
+    return result;
+}
+
+
+// --- InputMapper ---
+
+InputMapper::InputMapper(InputDevice* device) :
+        mDevice(device), mContext(device->getContext()) {
+}
+
+InputMapper::~InputMapper() {
+}
+
+void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    info->addSource(getSources());
+}
+
+void InputMapper::configure() {
+}
+
+void InputMapper::reset() {
+}
+
+int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    return false;
+}
+
+int32_t InputMapper::getMetaState() {
+    return 0;
+}
+
+bool InputMapper::applyStandardPolicyActions(nsecs_t when, int32_t policyActions) {
+    if (policyActions & InputReaderPolicyInterface::ACTION_APP_SWITCH_COMING) {
+        getDispatcher()->notifyAppSwitchComing(when);
+    }
+
+    return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH;
+}
+
+
+// --- SwitchInputMapper ---
+
+SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
+        InputMapper(device) {
+}
+
+SwitchInputMapper::~SwitchInputMapper() {
+}
+
+uint32_t SwitchInputMapper::getSources() {
+    return 0;
+}
+
+void SwitchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_SW:
+        processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
+        break;
+    }
+}
+
+void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
+    uint32_t policyFlags = 0;
+    int32_t policyActions = getPolicy()->interceptSwitch(
+            when, switchCode, switchValue, policyFlags);
+
+    applyStandardPolicyActions(when, policyActions);
+}
+
+int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
+}
+
+
+// --- KeyboardInputMapper ---
+
+KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId,
+        uint32_t sources, int32_t keyboardType) :
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
+        mKeyboardType(keyboardType) {
+    initializeLocked();
+}
+
+KeyboardInputMapper::~KeyboardInputMapper() {
+}
+
+void KeyboardInputMapper::initializeLocked() {
+    mLocked.metaState = AMETA_NONE;
+    mLocked.downTime = 0;
+}
+
+uint32_t KeyboardInputMapper::getSources() {
+    return mSources;
+}
+
+void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->setKeyboardType(mKeyboardType);
+}
+
+void KeyboardInputMapper::reset() {
+    for (;;) {
+        int32_t keyCode, scanCode;
+        { // acquire lock
+            AutoMutex _l(mLock);
+
+            // Synthesize key up event on reset if keys are currently down.
+            if (mLocked.keyDowns.isEmpty()) {
+                initializeLocked();
+                break; // done
+            }
+
+            const KeyDown& keyDown = mLocked.keyDowns.top();
+            keyCode = keyDown.keyCode;
+            scanCode = keyDown.scanCode;
+        } // release lock
+
+        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        processKey(when, false, keyCode, scanCode, 0);
+    }
+
+    InputMapper::reset();
+    getContext()->updateGlobalMetaState();
+}
+
+void KeyboardInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY: {
+        int32_t scanCode = rawEvent->scanCode;
+        if (isKeyboardOrGamepadKey(scanCode)) {
+            processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
+                    rawEvent->flags);
+        }
+        break;
+    }
+    }
+}
+
+bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
+    return scanCode < BTN_MOUSE
+        || scanCode >= KEY_OK
+        || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
+}
+
+void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
+        int32_t scanCode, uint32_t policyFlags) {
+    int32_t newMetaState;
+    nsecs_t downTime;
+    bool metaStateChanged = false;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (down) {
+            // Rotate key codes according to orientation if needed.
+            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+            if (mAssociatedDisplayId >= 0) {
+                int32_t orientation;
+                if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+                    return;
+                }
+
+                keyCode = rotateKeyCode(keyCode, orientation);
+            }
+
+            // Add key down.
+            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+            if (keyDownIndex >= 0) {
+                // key repeat, be sure to use same keycode as before in case of rotation
+                keyCode = mLocked.keyDowns.top().keyCode;
+            } else {
+                // key down
+                mLocked.keyDowns.push();
+                KeyDown& keyDown = mLocked.keyDowns.editTop();
+                keyDown.keyCode = keyCode;
+                keyDown.scanCode = scanCode;
+            }
+
+            mLocked.downTime = when;
+        } else {
+            // Remove key down.
+            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+            if (keyDownIndex >= 0) {
+                // key up, be sure to use same keycode as before in case of rotation
+                keyCode = mLocked.keyDowns.top().keyCode;
+                mLocked.keyDowns.removeAt(size_t(keyDownIndex));
+            } else {
+                // key was not actually down
+                LOGI("Dropping key up from device %s because the key was not down.  "
+                        "keyCode=%d, scanCode=%d",
+                        getDeviceName().string(), keyCode, scanCode);
+                return;
+            }
+        }
+
+        int32_t oldMetaState = mLocked.metaState;
+        newMetaState = updateMetaState(keyCode, down, oldMetaState);
+        if (oldMetaState != newMetaState) {
+            mLocked.metaState = newMetaState;
+            metaStateChanged = true;
+        }
+
+        downTime = mLocked.downTime;
+    } // release lock
+
+    if (metaStateChanged) {
+        getContext()->updateGlobalMetaState();
+    }
+
+    applyPolicyAndDispatch(when, policyFlags, down, keyCode, scanCode, newMetaState, downTime);
+}
+
+void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags, bool down,
+        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
+    int32_t policyActions = getPolicy()->interceptKey(when,
+            getDeviceId(), down, keyCode, scanCode, policyFlags);
+
+    if (! applyStandardPolicyActions(when, policyActions)) {
+        return; // event dropped
+    }
+
+    int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP;
+    int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
+    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
+        keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
+    }
+
+    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+}
+
+ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
+    size_t n = mLocked.keyDowns.size();
+    for (size_t i = 0; i < n; i++) {
+        if (mLocked.keyDowns[i].scanCode == scanCode) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
+}
+
+int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+}
+
+bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
+}
+
+int32_t KeyboardInputMapper::getMetaState() {
+    { // acquire lock
+        AutoMutex _l(mLock);
+        return mLocked.metaState;
+    } // release lock
+}
+
+
+// --- TrackballInputMapper ---
+
+TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+    mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+    mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+    mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+    mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+
+    initializeLocked();
+}
+
+TrackballInputMapper::~TrackballInputMapper() {
+}
+
+uint32_t TrackballInputMapper::getSources() {
+    return AINPUT_SOURCE_TRACKBALL;
+}
+
+void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale);
+    info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
+}
+
+void TrackballInputMapper::initializeLocked() {
+    mAccumulator.clear();
+
+    mLocked.down = false;
+    mLocked.downTime = 0;
+}
+
+void TrackballInputMapper::reset() {
+    for (;;) {
+        { // acquire lock
+            AutoMutex _l(mLock);
+
+            if (! mLocked.down) {
+                initializeLocked();
+                break; // done
+            }
+        } // release lock
+
+        // Synthesize trackball button up event on reset.
+        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
+        mAccumulator.btnMouse = false;
+        sync(when);
+    }
+
+    InputMapper::reset();
+}
+
+void TrackballInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY:
+        switch (rawEvent->scanCode) {
+        case BTN_MOUSE:
+            mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
+            mAccumulator.btnMouse = rawEvent->value != 0;
+            // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
+            // we need to ensure that we report the up/down promptly.
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+
+    case EV_REL:
+        switch (rawEvent->scanCode) {
+        case REL_X:
+            mAccumulator.fields |= Accumulator::FIELD_REL_X;
+            mAccumulator.relX = rawEvent->value;
+            break;
+        case REL_Y:
+            mAccumulator.fields |= Accumulator::FIELD_REL_Y;
+            mAccumulator.relY = rawEvent->value;
+            break;
+        }
+        break;
+
+    case EV_SYN:
+        switch (rawEvent->scanCode) {
+        case SYN_REPORT:
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+    }
+}
+
+void TrackballInputMapper::sync(nsecs_t when) {
+    uint32_t fields = mAccumulator.fields;
+    if (fields == 0) {
+        return; // no new state changes, so nothing to do
+    }
+
+    int motionEventAction;
+    PointerCoords pointerCoords;
+    nsecs_t downTime;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
+
+        if (downChanged) {
+            if (mAccumulator.btnMouse) {
+                mLocked.down = true;
+                mLocked.downTime = when;
+            } else {
+                mLocked.down = false;
+            }
+        }
+
+        downTime = mLocked.downTime;
+        float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
+        float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
+
+        if (downChanged) {
+            motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+        } else {
+            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+        }
+
+        pointerCoords.x = x;
+        pointerCoords.y = y;
+        pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
+        pointerCoords.size = 0;
+        pointerCoords.touchMajor = 0;
+        pointerCoords.touchMinor = 0;
+        pointerCoords.toolMajor = 0;
+        pointerCoords.toolMinor = 0;
+        pointerCoords.orientation = 0;
+
+        if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
+            // Rotate motion based on display orientation if needed.
+            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+            int32_t orientation;
+            if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+                return;
+            }
+
+            float temp;
+            switch (orientation) {
+            case InputReaderPolicyInterface::ROTATION_90:
+                temp = pointerCoords.x;
+                pointerCoords.x = pointerCoords.y;
+                pointerCoords.y = - temp;
+                break;
+
+            case InputReaderPolicyInterface::ROTATION_180:
+                pointerCoords.x = - pointerCoords.x;
+                pointerCoords.y = - pointerCoords.y;
+                break;
+
+            case InputReaderPolicyInterface::ROTATION_270:
+                temp = pointerCoords.x;
+                pointerCoords.x = - pointerCoords.y;
+                pointerCoords.y = temp;
+                break;
+            }
+        }
+    } // release lock
+
+    applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
+
+    mAccumulator.clear();
+}
+
+void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+        PointerCoords* pointerCoords, nsecs_t downTime) {
+    uint32_t policyFlags = 0;
+    int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
+
+    if (! applyStandardPolicyActions(when, policyActions)) {
+        return; // event dropped
+    }
+
+    int32_t metaState = mContext->getGlobalMetaState();
+    int32_t pointerId = 0;
+
+    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
+            motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+            1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
+}
+
+int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
+        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+    } else {
+        return AKEY_STATE_UNKNOWN;
+    }
+}
+
+
+// --- TouchInputMapper ---
+
+TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+    mLocked.surfaceOrientation = -1;
+    mLocked.surfaceWidth = -1;
+    mLocked.surfaceHeight = -1;
+
+    initializeLocked();
+}
+
+TouchInputMapper::~TouchInputMapper() {
+}
+
+uint32_t TouchInputMapper::getSources() {
+    return mAssociatedDisplayId >= 0 ? AINPUT_SOURCE_TOUCHSCREEN : AINPUT_SOURCE_TOUCHPAD;
+}
+
+void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Ensure surface information is up to date so that orientation changes are
+        // noticed immediately.
+        configureSurfaceLocked();
+
+        info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
+        info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+
+        if (mLocked.orientedRanges.havePressure) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
+                    mLocked.orientedRanges.pressure);
+        }
+
+        if (mLocked.orientedRanges.haveSize) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
+                    mLocked.orientedRanges.size);
+        }
+
+        if (mLocked.orientedRanges.haveTouchArea) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+                    mLocked.orientedRanges.touchMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+                    mLocked.orientedRanges.touchMinor);
+        }
+
+        if (mLocked.orientedRanges.haveToolArea) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
+                    mLocked.orientedRanges.toolMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
+                    mLocked.orientedRanges.toolMinor);
+        }
+
+        if (mLocked.orientedRanges.haveOrientation) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
+                    mLocked.orientedRanges.orientation);
+        }
+    } // release lock
+}
+
+void TouchInputMapper::initializeLocked() {
+    mCurrentTouch.clear();
+    mLastTouch.clear();
+    mDownTime = 0;
+
+    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
+        mAveragingTouchFilter.historyStart[i] = 0;
+        mAveragingTouchFilter.historyEnd[i] = 0;
+    }
+
+    mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+    mLocked.currentVirtualKey.down = false;
+
+    mLocked.orientedRanges.havePressure = false;
+    mLocked.orientedRanges.haveSize = false;
+    mLocked.orientedRanges.haveTouchArea = false;
+    mLocked.orientedRanges.haveToolArea = false;
+    mLocked.orientedRanges.haveOrientation = false;
+}
+
+static void logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) {
+    if (axis.valid) {
+        LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d",
+                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
+    } else {
+        LOGI(INDENT "Raw %s axis: unknown range", name);
+    }
+}
+
+void TouchInputMapper::configure() {
+    InputMapper::configure();
+
+    // Configure basic parameters.
+    configureParameters();
+
+    // Configure absolute axis information.
+    configureRawAxes();
+    logRawAxes();
+
+    // Prepare input device calibration.
+    parseCalibration();
+    resolveCalibration();
+    logCalibration();
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+         // Configure surface dimensions and orientation.
+        configureSurfaceLocked();
+    } // release lock
+}
+
+void TouchInputMapper::configureParameters() {
+    mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
+    mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
+    mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+}
+
+void TouchInputMapper::configureRawAxes() {
+    mRawAxes.x.clear();
+    mRawAxes.y.clear();
+    mRawAxes.pressure.clear();
+    mRawAxes.touchMajor.clear();
+    mRawAxes.touchMinor.clear();
+    mRawAxes.toolMajor.clear();
+    mRawAxes.toolMinor.clear();
+    mRawAxes.orientation.clear();
+}
+
+void TouchInputMapper::logRawAxes() {
+    logAxisInfo(mRawAxes.x, "x");
+    logAxisInfo(mRawAxes.y, "y");
+    logAxisInfo(mRawAxes.pressure, "pressure");
+    logAxisInfo(mRawAxes.touchMajor, "touchMajor");
+    logAxisInfo(mRawAxes.touchMinor, "touchMinor");
+    logAxisInfo(mRawAxes.toolMajor, "toolMajor");
+    logAxisInfo(mRawAxes.toolMinor, "toolMinor");
+    logAxisInfo(mRawAxes.orientation, "orientation");
+}
+
+bool TouchInputMapper::configureSurfaceLocked() {
+    // Update orientation and dimensions if needed.
+    int32_t orientation;
+    int32_t width, height;
+    if (mAssociatedDisplayId >= 0) {
+        // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+        if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
+            return false;
+        }
+    } else {
+        orientation = InputReaderPolicyInterface::ROTATION_0;
+        width = mRawAxes.x.getRange();
+        height = mRawAxes.y.getRange();
+    }
+
+    bool orientationChanged = mLocked.surfaceOrientation != orientation;
+    if (orientationChanged) {
+        mLocked.surfaceOrientation = orientation;
+    }
+
+    bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
+    if (sizeChanged) {
+        LOGI("Device configured: id=0x%x, name=%s (display size was changed)",
+                getDeviceId(), getDeviceName().string());
+
+        mLocked.surfaceWidth = width;
+        mLocked.surfaceHeight = height;
+
+        // Configure X and Y factors.
+        if (mRawAxes.x.valid && mRawAxes.y.valid) {
+            mLocked.xOrigin = mRawAxes.x.minValue;
+            mLocked.yOrigin = mRawAxes.y.minValue;
+            mLocked.xScale = float(width) / mRawAxes.x.getRange();
+            mLocked.yScale = float(height) / mRawAxes.y.getRange();
+            mLocked.xPrecision = 1.0f / mLocked.xScale;
+            mLocked.yPrecision = 1.0f / mLocked.yScale;
+
+            configureVirtualKeysLocked();
+        } else {
+            LOGW(INDENT "Touch device did not report support for X or Y axis!");
+            mLocked.xOrigin = 0;
+            mLocked.yOrigin = 0;
+            mLocked.xScale = 1.0f;
+            mLocked.yScale = 1.0f;
+            mLocked.xPrecision = 1.0f;
+            mLocked.yPrecision = 1.0f;
+        }
+
+        // Scale factor for terms that are not oriented in a particular axis.
+        // If the pixels are square then xScale == yScale otherwise we fake it
+        // by choosing an average.
+        mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
+
+        // Size of diagonal axis.
+        float diagonalSize = pythag(width, height);
+
+        // TouchMajor and TouchMinor factors.
+        if (mCalibration.touchAreaCalibration != Calibration::TOUCH_AREA_CALIBRATION_NONE) {
+            mLocked.orientedRanges.haveTouchArea = true;
+            mLocked.orientedRanges.touchMajor.min = 0;
+            mLocked.orientedRanges.touchMajor.max = diagonalSize;
+            mLocked.orientedRanges.touchMajor.flat = 0;
+            mLocked.orientedRanges.touchMajor.fuzz = 0;
+            mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
+        }
+
+        // ToolMajor and ToolMinor factors.
+        if (mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+            mLocked.toolAreaLinearScale = 0;
+            mLocked.toolAreaLinearBias = 0;
+            if (mCalibration.toolAreaCalibration == Calibration::TOOL_AREA_CALIBRATION_LINEAR) {
+                if (mCalibration.haveToolAreaLinearScale) {
+                    mLocked.toolAreaLinearScale = mCalibration.toolAreaLinearScale;
+                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.toolAreaLinearScale = float(min(width, height))
+                            / mRawAxes.toolMajor.maxValue;
+                }
+
+                if (mCalibration.haveToolAreaLinearBias) {
+                    mLocked.toolAreaLinearBias = mCalibration.toolAreaLinearBias;
+                }
+            }
+
+            mLocked.orientedRanges.haveToolArea = true;
+            mLocked.orientedRanges.toolMajor.min = 0;
+            mLocked.orientedRanges.toolMajor.max = diagonalSize;
+            mLocked.orientedRanges.toolMajor.flat = 0;
+            mLocked.orientedRanges.toolMajor.fuzz = 0;
+            mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
+        }
+
+        // Pressure factors.
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
+            RawAbsoluteAxisInfo rawPressureAxis;
+            switch (mCalibration.pressureSource) {
+            case Calibration::PRESSURE_SOURCE_PRESSURE:
+                rawPressureAxis = mRawAxes.pressure;
+                break;
+            case Calibration::PRESSURE_SOURCE_TOUCH:
+                rawPressureAxis = mRawAxes.touchMajor;
+                break;
+            default:
+                rawPressureAxis.clear();
+            }
+
+            mLocked.pressureScale = 0;
+            if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
+                    || mCalibration.pressureCalibration
+                            == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
+                if (mCalibration.havePressureScale) {
+                    mLocked.pressureScale = mCalibration.pressureScale;
+                } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
+                    mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.havePressure = true;
+            mLocked.orientedRanges.pressure.min = 0;
+            mLocked.orientedRanges.pressure.max = 1.0;
+            mLocked.orientedRanges.pressure.flat = 0;
+            mLocked.orientedRanges.pressure.fuzz = 0;
+        }
+
+        // Size factors.
+        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
+            mLocked.sizeScale = 0;
+            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
+                if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.haveSize = true;
+            mLocked.orientedRanges.size.min = 0;
+            mLocked.orientedRanges.size.max = 1.0;
+            mLocked.orientedRanges.size.flat = 0;
+            mLocked.orientedRanges.size.fuzz = 0;
+        }
+
+        // Orientation
+        if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
+            mLocked.orientationScale = 0;
+            if (mCalibration.orientationCalibration
+                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
+                if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
+                    mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.orientation.min = - M_PI_2;
+            mLocked.orientedRanges.orientation.max = M_PI_2;
+            mLocked.orientedRanges.orientation.flat = 0;
+            mLocked.orientedRanges.orientation.fuzz = 0;
+        }
+    }
+
+    if (orientationChanged || sizeChanged) {
+        // Compute oriented surface dimensions, precision, and scales.
+        float orientedXScale, orientedYScale;
+        switch (mLocked.surfaceOrientation) {
+        case InputReaderPolicyInterface::ROTATION_90:
+        case InputReaderPolicyInterface::ROTATION_270:
+            mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
+            mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
+            mLocked.orientedXPrecision = mLocked.yPrecision;
+            mLocked.orientedYPrecision = mLocked.xPrecision;
+            orientedXScale = mLocked.yScale;
+            orientedYScale = mLocked.xScale;
+            break;
+        default:
+            mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
+            mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
+            mLocked.orientedXPrecision = mLocked.xPrecision;
+            mLocked.orientedYPrecision = mLocked.yPrecision;
+            orientedXScale = mLocked.xScale;
+            orientedYScale = mLocked.yScale;
+            break;
+        }
+
+        // Configure position ranges.
+        mLocked.orientedRanges.x.min = 0;
+        mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
+        mLocked.orientedRanges.x.flat = 0;
+        mLocked.orientedRanges.x.fuzz = orientedXScale;
+
+        mLocked.orientedRanges.y.min = 0;
+        mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
+        mLocked.orientedRanges.y.flat = 0;
+        mLocked.orientedRanges.y.fuzz = orientedYScale;
+    }
+
+    return true;
+}
+
+void TouchInputMapper::configureVirtualKeysLocked() {
+    assert(mRawAxes.x.valid && mRawAxes.y.valid);
+
+    // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
+    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
+    getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
+
+    mLocked.virtualKeys.clear();
+
+    if (virtualKeyDefinitions.size() == 0) {
+        return;
+    }
+
+    mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+
+    int32_t touchScreenLeft = mRawAxes.x.minValue;
+    int32_t touchScreenTop = mRawAxes.y.minValue;
+    int32_t touchScreenWidth = mRawAxes.x.getRange();
+    int32_t touchScreenHeight = mRawAxes.y.getRange();
+
+    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+        const VirtualKeyDefinition& virtualKeyDefinition =
+                virtualKeyDefinitions[i];
+
+        mLocked.virtualKeys.add();
+        VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+
+        virtualKey.scanCode = virtualKeyDefinition.scanCode;
+        int32_t keyCode;
+        uint32_t flags;
+        if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+                & keyCode, & flags)) {
+            LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
+                    virtualKey.scanCode);
+            mLocked.virtualKeys.pop(); // drop the key
+            continue;
+        }
+
+        virtualKey.keyCode = keyCode;
+        virtualKey.flags = flags;
+
+        // convert the key definition's display coordinates into touch coordinates for a hit box
+        int32_t halfWidth = virtualKeyDefinition.width / 2;
+        int32_t halfHeight = virtualKeyDefinition.height / 2;
+
+        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
+                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+
+        LOGI(INDENT "VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+                virtualKey.scanCode, virtualKey.keyCode,
+                virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
+    }
+}
+
+void TouchInputMapper::parseCalibration() {
+    const InputDeviceCalibration& in = getDevice()->getCalibration();
+    Calibration& out = mCalibration;
+
+    // Touch Area
+    out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_DEFAULT;
+    String8 touchAreaCalibrationString;
+    if (in.tryGetProperty(String8("touch.touchArea.calibration"), touchAreaCalibrationString)) {
+        if (touchAreaCalibrationString == "none") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+        } else if (touchAreaCalibrationString == "geometric") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC;
+        } else if (touchAreaCalibrationString == "pressure") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+        } else if (touchAreaCalibrationString != "default") {
+            LOGW("Invalid value for touch.touchArea.calibration: '%s'",
+                    touchAreaCalibrationString.string());
+        }
+    }
+
+    // Tool Area
+    out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_DEFAULT;
+    String8 toolAreaCalibrationString;
+    if (in.tryGetProperty(String8("tool.toolArea.calibration"), toolAreaCalibrationString)) {
+        if (toolAreaCalibrationString == "none") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+        } else if (toolAreaCalibrationString == "geometric") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC;
+        } else if (toolAreaCalibrationString == "linear") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+        } else if (toolAreaCalibrationString != "default") {
+            LOGW("Invalid value for tool.toolArea.calibration: '%s'",
+                    toolAreaCalibrationString.string());
+        }
+    }
+
+    out.haveToolAreaLinearScale = in.tryGetProperty(String8("touch.toolArea.linearScale"),
+            out.toolAreaLinearScale);
+    out.haveToolAreaLinearBias = in.tryGetProperty(String8("touch.toolArea.linearBias"),
+            out.toolAreaLinearBias);
+    out.haveToolAreaIsSummed = in.tryGetProperty(String8("touch.toolArea.isSummed"),
+            out.toolAreaIsSummed);
+
+    // Pressure
+    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
+    String8 pressureCalibrationString;
+    if (in.tryGetProperty(String8("tool.pressure.calibration"), pressureCalibrationString)) {
+        if (pressureCalibrationString == "none") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+        } else if (pressureCalibrationString == "physical") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
+        } else if (pressureCalibrationString == "amplitude") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+        } else if (pressureCalibrationString != "default") {
+            LOGW("Invalid value for tool.pressure.calibration: '%s'",
+                    pressureCalibrationString.string());
+        }
+    }
+
+    out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
+    String8 pressureSourceString;
+    if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
+        if (pressureSourceString == "pressure") {
+            out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+        } else if (pressureSourceString == "touch") {
+            out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+        } else if (pressureSourceString != "default") {
+            LOGW("Invalid value for touch.pressure.source: '%s'",
+                    pressureSourceString.string());
+        }
+    }
+
+    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
+            out.pressureScale);
+
+    // Size
+    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
+    String8 sizeCalibrationString;
+    if (in.tryGetProperty(String8("tool.size.calibration"), sizeCalibrationString)) {
+        if (sizeCalibrationString == "none") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+        } else if (sizeCalibrationString == "normalized") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+        } else if (sizeCalibrationString != "default") {
+            LOGW("Invalid value for tool.size.calibration: '%s'",
+                    sizeCalibrationString.string());
+        }
+    }
+
+    // Orientation
+    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
+    String8 orientationCalibrationString;
+    if (in.tryGetProperty(String8("tool.orientation.calibration"), orientationCalibrationString)) {
+        if (orientationCalibrationString == "none") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+        } else if (orientationCalibrationString == "interpolated") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else if (orientationCalibrationString != "default") {
+            LOGW("Invalid value for tool.orientation.calibration: '%s'",
+                    orientationCalibrationString.string());
+        }
+    }
+}
+
+void TouchInputMapper::resolveCalibration() {
+    // Pressure
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        if (mRawAxes.pressure.valid) {
+            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+        } else if (mRawAxes.touchMajor.valid) {
+            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+        }
+        break;
+
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        if (! mRawAxes.pressure.valid) {
+            LOGW("Calibration property touch.pressure.source is 'pressure' but "
+                    "the pressure axis is not available.");
+        }
+        break;
+
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        if (! mRawAxes.touchMajor.valid) {
+            LOGW("Calibration property touch.pressure.source is 'touch' but "
+                    "the touchMajor axis is not available.");
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+        } else {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Tool Area
+    switch (mCalibration.toolAreaCalibration) {
+    case Calibration::TOOL_AREA_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+        } else {
+            mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Touch Area
+    switch (mCalibration.touchAreaCalibration) {
+    case Calibration::TOUCH_AREA_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
+                && mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+            mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+        } else {
+            mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+        } else {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
+        if (mRawAxes.orientation.valid) {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+void TouchInputMapper::logCalibration() {
+    // Touch Area
+    switch (mCalibration.touchAreaCalibration) {
+    case Calibration::TOUCH_AREA_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.touchArea.calibration: none");
+        break;
+    case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+        LOGI(INDENT "  touch.touchArea.calibration: geometric");
+        break;
+    case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+        LOGI(INDENT "  touch.touchArea.calibration: pressure");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Tool Area
+    switch (mCalibration.toolAreaCalibration) {
+    case Calibration::TOOL_AREA_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.toolArea.calibration: none");
+        break;
+    case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+        LOGI(INDENT "  touch.toolArea.calibration: geometric");
+        break;
+    case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+        LOGI(INDENT "  touch.toolArea.calibration: linear");
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.haveToolAreaLinearScale) {
+        LOGI(INDENT "  touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale);
+    }
+
+    if (mCalibration.haveToolAreaLinearBias) {
+        LOGI(INDENT "  touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias);
+    }
+
+    if (mCalibration.haveToolAreaIsSummed) {
+        LOGI(INDENT "  touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed);
+    }
+
+    // Pressure
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.pressure.calibration: none");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+        LOGI(INDENT "  touch.pressure.calibration: physical");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+        LOGI(INDENT "  touch.pressure.calibration: amplitude");
+        break;
+    default:
+        assert(false);
+    }
+
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        LOGI(INDENT "  touch.pressure.source: pressure");
+        break;
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        LOGI(INDENT "  touch.pressure.source: touch");
+        break;
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.havePressureScale) {
+        LOGI(INDENT "  touch.pressure.scale: %f", mCalibration.pressureScale);
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.size.calibration: none");
+        break;
+    case Calibration::SIZE_CALIBRATION_NORMALIZED:
+        LOGI(INDENT "  touch.size.calibration: normalized");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_NONE:
+        LOGI(INDENT "  touch.orientation.calibration: none");
+        break;
+    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+        LOGI(INDENT "  touch.orientation.calibration: interpolated");
+        break;
+    default:
+        assert(false);
+    }
+}
+
+void TouchInputMapper::reset() {
+    // Synthesize touch up event if touch is currently down.
+    // This will also take care of finishing virtual key processing if needed.
+    if (mLastTouch.pointerCount != 0) {
+        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        mCurrentTouch.clear();
+        syncTouch(when, true);
+    }
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+        initializeLocked();
+    } // release lock
+
+    InputMapper::reset();
+}
+
+void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
+    // Apply generic policy actions.
+
+    uint32_t policyFlags = 0;
+    int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
+
+    if (! applyStandardPolicyActions(when, policyActions)) {
+        mLastTouch.clear();
+        return; // event dropped
+    }
+
+    // Preprocess pointer data.
+
+    if (mParameters.useBadTouchFilter) {
+        if (applyBadTouchFilter()) {
+            havePointerIds = false;
+        }
+    }
+
+    if (mParameters.useJumpyTouchFilter) {
+        if (applyJumpyTouchFilter()) {
+            havePointerIds = false;
+        }
+    }
+
+    if (! havePointerIds) {
+        calculatePointerIds();
+    }
+
+    TouchData temp;
+    TouchData* savedTouch;
+    if (mParameters.useAveragingTouchFilter) {
+        temp.copyFrom(mCurrentTouch);
+        savedTouch = & temp;
+
+        applyAveragingTouchFilter();
+    } else {
+        savedTouch = & mCurrentTouch;
+    }
+
+    // Process touches and virtual keys.
+
+    TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
+    if (touchResult == DISPATCH_TOUCH) {
+        dispatchTouches(when, policyFlags);
+    }
+
+    // Copy current touch to last touch in preparation for the next cycle.
+
+    if (touchResult == DROP_STROKE) {
+        mLastTouch.clear();
+    } else {
+        mLastTouch.copyFrom(*savedTouch);
+    }
+}
+
+TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
+        nsecs_t when, uint32_t policyFlags) {
+    int32_t keyEventAction, keyEventFlags;
+    int32_t keyCode, scanCode, downTime;
+    TouchResult touchResult;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Update surface size and orientation, including virtual key positions.
+        if (! configureSurfaceLocked()) {
+            return DROP_STROKE;
+        }
+
+        // Check for virtual key press.
+        if (mLocked.currentVirtualKey.down) {
+            if (mCurrentTouch.pointerCount == 0) {
+                // Pointer went up while virtual key was down.
+                mLocked.currentVirtualKey.down = false;
+#if DEBUG_VIRTUAL_KEYS
+                LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
+                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+                keyEventAction = AKEY_EVENT_ACTION_UP;
+                keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
+                touchResult = SKIP_TOUCH;
+                goto DispatchVirtualKey;
+            }
+
+            if (mCurrentTouch.pointerCount == 1) {
+                int32_t x = mCurrentTouch.pointers[0].x;
+                int32_t y = mCurrentTouch.pointers[0].y;
+                const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+                if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
+                    // Pointer is still within the space of the virtual key.
+                    return SKIP_TOUCH;
+                }
+            }
+
+            // Pointer left virtual key area or another pointer also went down.
+            // Send key cancellation and drop the stroke so subsequent motions will be
+            // considered fresh downs.  This is useful when the user swipes away from the
+            // virtual key area into the main display surface.
+            mLocked.currentVirtualKey.down = false;
+#if DEBUG_VIRTUAL_KEYS
+            LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
+                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+            keyEventAction = AKEY_EVENT_ACTION_UP;
+            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+                    | AKEY_EVENT_FLAG_CANCELED;
+            touchResult = DROP_STROKE;
+            goto DispatchVirtualKey;
+        } else {
+            if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
+                // Pointer just went down.  Handle off-screen touches, if needed.
+                int32_t x = mCurrentTouch.pointers[0].x;
+                int32_t y = mCurrentTouch.pointers[0].y;
+                if (! isPointInsideSurfaceLocked(x, y)) {
+                    // If exactly one pointer went down, check for virtual key hit.
+                    // Otherwise we will drop the entire stroke.
+                    if (mCurrentTouch.pointerCount == 1) {
+                        const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+                        if (virtualKey) {
+                            mLocked.currentVirtualKey.down = true;
+                            mLocked.currentVirtualKey.downTime = when;
+                            mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
+                            mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
+#if DEBUG_VIRTUAL_KEYS
+                            LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+                                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+                            keyEventAction = AKEY_EVENT_ACTION_DOWN;
+                            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
+                                    | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
+                            touchResult = SKIP_TOUCH;
+                            goto DispatchVirtualKey;
+                        }
+                    }
+                    return DROP_STROKE;
+                }
+            }
+            return DISPATCH_TOUCH;
+        }
+
+    DispatchVirtualKey:
+        // Collect remaining state needed to dispatch virtual key.
+        keyCode = mLocked.currentVirtualKey.keyCode;
+        scanCode = mLocked.currentVirtualKey.scanCode;
+        downTime = mLocked.currentVirtualKey.downTime;
+    } // release lock
+
+    // Dispatch virtual key.
+    applyPolicyAndDispatchVirtualKey(when, policyFlags, keyEventAction, keyEventFlags,
+            keyCode, scanCode, downTime);
+    return touchResult;
+}
+
+void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+        int32_t keyEventAction, int32_t keyEventFlags,
+        int32_t keyCode, int32_t scanCode, nsecs_t downTime) {
+    int32_t metaState = mContext->getGlobalMetaState();
+
+    if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
+        getPolicy()->virtualKeyDownFeedback();
+    }
+
+    int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(),
+            keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
+
+    if (applyStandardPolicyActions(when, policyActions)) {
+        getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+                keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+    }
+}
+
+void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
+    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
+    uint32_t lastPointerCount = mLastTouch.pointerCount;
+    if (currentPointerCount == 0 && lastPointerCount == 0) {
+        return; // nothing to do!
+    }
+
+    BitSet32 currentIdBits = mCurrentTouch.idBits;
+    BitSet32 lastIdBits = mLastTouch.idBits;
+
+    if (currentIdBits == lastIdBits) {
+        // No pointer id changes so this is a move event.
+        // The dispatcher takes care of batching moves so we don't have to deal with that here.
+        int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+        dispatchTouch(when, policyFlags, & mCurrentTouch,
+                currentIdBits, -1, currentPointerCount, motionEventAction);
+    } else {
+        // There may be pointers going up and pointers going down at the same time when pointer
+        // ids are reported by the device driver.
+        BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
+        BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
+        BitSet32 activeIdBits(lastIdBits.value);
+        uint32_t pointerCount = lastPointerCount;
+
+        while (! upIdBits.isEmpty()) {
+            uint32_t upId = upIdBits.firstMarkedBit();
+            upIdBits.clearBit(upId);
+            BitSet32 oldActiveIdBits = activeIdBits;
+            activeIdBits.clearBit(upId);
+
+            int32_t motionEventAction;
+            if (activeIdBits.isEmpty()) {
+                motionEventAction = AMOTION_EVENT_ACTION_UP;
+            } else {
+                motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
+            }
+
+            dispatchTouch(when, policyFlags, & mLastTouch,
+                    oldActiveIdBits, upId, pointerCount, motionEventAction);
+            pointerCount -= 1;
+        }
+
+        while (! downIdBits.isEmpty()) {
+            uint32_t downId = downIdBits.firstMarkedBit();
+            downIdBits.clearBit(downId);
+            BitSet32 oldActiveIdBits = activeIdBits;
+            activeIdBits.markBit(downId);
+
+            int32_t motionEventAction;
+            if (oldActiveIdBits.isEmpty()) {
+                motionEventAction = AMOTION_EVENT_ACTION_DOWN;
+                mDownTime = when;
+            } else {
+                motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
+            }
+
+            pointerCount += 1;
+            dispatchTouch(when, policyFlags, & mCurrentTouch,
+                    activeIdBits, downId, pointerCount, motionEventAction);
+        }
+    }
+}
+
+void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
+        TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
+        int32_t motionEventAction) {
+    int32_t pointerIds[MAX_POINTERS];
+    PointerCoords pointerCoords[MAX_POINTERS];
+    int32_t motionEventEdgeFlags = 0;
+    float xPrecision, yPrecision;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Walk through the the active pointers and map touch screen coordinates (TouchData) into
+        // display coordinates (PointerCoords) and adjust for display orientation.
+        for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
+            uint32_t id = idBits.firstMarkedBit();
+            idBits.clearBit(id);
+            uint32_t inIndex = touch->idToIndex[id];
+
+            const PointerData& in = touch->pointers[inIndex];
+
+            // X and Y
+            float x = float(in.x - mLocked.xOrigin) * mLocked.xScale;
+            float y = float(in.y - mLocked.yOrigin) * mLocked.yScale;
+
+            // ToolMajor and ToolMinor
+            float toolMajor, toolMinor;
+            switch (mCalibration.toolAreaCalibration) {
+            case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+                toolMajor = in.toolMajor * mLocked.geometricScale;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor * mLocked.geometricScale;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+                toolMajor = in.toolMajor != 0
+                        ? in.toolMajor * mLocked.toolAreaLinearScale + mLocked.toolAreaLinearBias
+                        : 0;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor != 0
+                            ? in.toolMinor * mLocked.toolAreaLinearScale
+                                    + mLocked.toolAreaLinearBias
+                            : 0;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            default:
+                toolMajor = 0;
+                toolMinor = 0;
+                break;
+            }
+
+            if (mCalibration.haveToolAreaIsSummed && mCalibration.toolAreaIsSummed) {
+                toolMajor /= pointerCount;
+                toolMinor /= pointerCount;
+            }
+
+            // Pressure
+            float rawPressure;
+            switch (mCalibration.pressureSource) {
+            case Calibration::PRESSURE_SOURCE_PRESSURE:
+                rawPressure = in.pressure;
+                break;
+            case Calibration::PRESSURE_SOURCE_TOUCH:
+                rawPressure = in.touchMajor;
+                break;
+            default:
+                rawPressure = 0;
+            }
+
+            float pressure;
+            switch (mCalibration.pressureCalibration) {
+            case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+            case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+                pressure = rawPressure * mLocked.pressureScale;
+                break;
+            default:
+                pressure = 1;
+                break;
+            }
+
+            // TouchMajor and TouchMinor
+            float touchMajor, touchMinor;
+            switch (mCalibration.touchAreaCalibration) {
+            case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+                touchMajor = in.touchMajor * mLocked.geometricScale;
+                if (mRawAxes.touchMinor.valid) {
+                    touchMinor = in.touchMinor * mLocked.geometricScale;
+                } else {
+                    touchMinor = touchMajor;
+                }
+                break;
+            case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+                touchMajor = toolMajor * pressure;
+                touchMinor = toolMinor * pressure;
+                break;
+            default:
+                touchMajor = 0;
+                touchMinor = 0;
+                break;
+            }
+
+            if (touchMajor > toolMajor) {
+                touchMajor = toolMajor;
+            }
+            if (touchMinor > toolMinor) {
+                touchMinor = toolMinor;
+            }
+
+            // Size
+            float size;
+            switch (mCalibration.sizeCalibration) {
+            case Calibration::SIZE_CALIBRATION_NORMALIZED: {
+                float rawSize = mRawAxes.toolMinor.valid
+                        ? avg(in.toolMajor, in.toolMinor)
+                        : in.toolMajor;
+                size = rawSize * mLocked.sizeScale;
+                break;
+            }
+            default:
+                size = 0;
+                break;
+            }
+
+            // Orientation
+            float orientation;
+            switch (mCalibration.orientationCalibration) {
+            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+                orientation = in.orientation * mLocked.orientationScale;
+                break;
+            default:
+                orientation = 0;
+            }
+
+            // Adjust coords for orientation.
+            switch (mLocked.surfaceOrientation) {
+            case InputReaderPolicyInterface::ROTATION_90: {
+                float xTemp = x;
+                x = y;
+                y = mLocked.surfaceWidth - xTemp;
+                orientation -= M_PI_2;
+                if (orientation < - M_PI_2) {
+                    orientation += M_PI;
+                }
+                break;
+            }
+            case InputReaderPolicyInterface::ROTATION_180: {
+                x = mLocked.surfaceWidth - x;
+                y = mLocked.surfaceHeight - y;
+                orientation = - orientation;
+                break;
+            }
+            case InputReaderPolicyInterface::ROTATION_270: {
+                float xTemp = x;
+                x = mLocked.surfaceHeight - y;
+                y = xTemp;
+                orientation += M_PI_2;
+                if (orientation > M_PI_2) {
+                    orientation -= M_PI;
+                }
+                break;
+            }
+            }
+
+            // Write output coords.
+            PointerCoords& out = pointerCoords[outIndex];
+            out.x = x;
+            out.y = y;
+            out.pressure = pressure;
+            out.size = size;
+            out.touchMajor = touchMajor;
+            out.touchMinor = touchMinor;
+            out.toolMajor = toolMajor;
+            out.toolMinor = toolMinor;
+            out.orientation = orientation;
+
+            pointerIds[outIndex] = int32_t(id);
+
+            if (id == changedId) {
+                motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+            }
+        }
+
+        // Check edge flags by looking only at the first pointer since the flags are
+        // global to the event.
+        if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
+            if (pointerCoords[0].x <= 0) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
+            } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+            }
+            if (pointerCoords[0].y <= 0) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
+            } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+            }
+        }
+
+        xPrecision = mLocked.orientedXPrecision;
+        yPrecision = mLocked.orientedYPrecision;
+    } // release lock
+
+    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags,
+            motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
+            pointerCount, pointerIds, pointerCoords,
+            xPrecision, yPrecision, mDownTime);
+}
+
+bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
+    if (mRawAxes.x.valid && mRawAxes.y.valid) {
+        return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
+                && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
+    }
+    return true;
+}
+
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+        int32_t x, int32_t y) {
+    size_t numVirtualKeys = mLocked.virtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+
+#if DEBUG_VIRTUAL_KEYS
+        LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
+                "left=%d, top=%d, right=%d, bottom=%d",
+                x, y,
+                virtualKey.keyCode, virtualKey.scanCode,
+                virtualKey.hitLeft, virtualKey.hitTop,
+                virtualKey.hitRight, virtualKey.hitBottom);
+#endif
+
+        if (virtualKey.isHit(x, y)) {
+            return & virtualKey;
+        }
+    }
+
+    return NULL;
+}
+
+void TouchInputMapper::calculatePointerIds() {
+    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
+    uint32_t lastPointerCount = mLastTouch.pointerCount;
+
+    if (currentPointerCount == 0) {
+        // No pointers to assign.
+        mCurrentTouch.idBits.clear();
+    } else if (lastPointerCount == 0) {
+        // All pointers are new.
+        mCurrentTouch.idBits.clear();
+        for (uint32_t i = 0; i < currentPointerCount; i++) {
+            mCurrentTouch.pointers[i].id = i;
+            mCurrentTouch.idToIndex[i] = i;
+            mCurrentTouch.idBits.markBit(i);
+        }
+    } else if (currentPointerCount == 1 && lastPointerCount == 1) {
+        // Only one pointer and no change in count so it must have the same id as before.
+        uint32_t id = mLastTouch.pointers[0].id;
+        mCurrentTouch.pointers[0].id = id;
+        mCurrentTouch.idToIndex[id] = 0;
+        mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
+    } else {
+        // General case.
+        // We build a heap of squared euclidean distances between current and last pointers
+        // associated with the current and last pointer indices.  Then, we find the best
+        // match (by distance) for each current pointer.
+        PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
+
+        uint32_t heapSize = 0;
+        for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
+                currentPointerIndex++) {
+            for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
+                    lastPointerIndex++) {
+                int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
+                        - mLastTouch.pointers[lastPointerIndex].x;
+                int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
+                        - mLastTouch.pointers[lastPointerIndex].y;
+
+                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
+
+                // Insert new element into the heap (sift up).
+                heap[heapSize].currentPointerIndex = currentPointerIndex;
+                heap[heapSize].lastPointerIndex = lastPointerIndex;
+                heap[heapSize].distance = distance;
+                heapSize += 1;
+            }
+        }
+
+        // Heapify
+        for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
+            startIndex -= 1;
+            for (uint32_t parentIndex = startIndex; ;) {
+                uint32_t childIndex = parentIndex * 2 + 1;
+                if (childIndex >= heapSize) {
+                    break;
+                }
+
+                if (childIndex + 1 < heapSize
+                        && heap[childIndex + 1].distance < heap[childIndex].distance) {
+                    childIndex += 1;
+                }
+
+                if (heap[parentIndex].distance <= heap[childIndex].distance) {
+                    break;
+                }
+
+                swap(heap[parentIndex], heap[childIndex]);
+                parentIndex = childIndex;
+            }
+        }
+
+#if DEBUG_POINTER_ASSIGNMENT
+        LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
+        for (size_t i = 0; i < heapSize; i++) {
+            LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
+                    i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+                    heap[i].distance);
+        }
+#endif
+
+        // Pull matches out by increasing order of distance.
+        // To avoid reassigning pointers that have already been matched, the loop keeps track
+        // of which last and current pointers have been matched using the matchedXXXBits variables.
+        // It also tracks the used pointer id bits.
+        BitSet32 matchedLastBits(0);
+        BitSet32 matchedCurrentBits(0);
+        BitSet32 usedIdBits(0);
+        bool first = true;
+        for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
+            for (;;) {
+                if (first) {
+                    // The first time through the loop, we just consume the root element of
+                    // the heap (the one with smallest distance).
+                    first = false;
+                } else {
+                    // Previous iterations consumed the root element of the heap.
+                    // Pop root element off of the heap (sift down).
+                    heapSize -= 1;
+                    assert(heapSize > 0);
+
+                    // Sift down.
+                    heap[0] = heap[heapSize];
+                    for (uint32_t parentIndex = 0; ;) {
+                        uint32_t childIndex = parentIndex * 2 + 1;
+                        if (childIndex >= heapSize) {
+                            break;
+                        }
+
+                        if (childIndex + 1 < heapSize
+                                && heap[childIndex + 1].distance < heap[childIndex].distance) {
+                            childIndex += 1;
+                        }
+
+                        if (heap[parentIndex].distance <= heap[childIndex].distance) {
+                            break;
+                        }
+
+                        swap(heap[parentIndex], heap[childIndex]);
+                        parentIndex = childIndex;
+                    }
+
+#if DEBUG_POINTER_ASSIGNMENT
+                    LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
+                    for (size_t i = 0; i < heapSize; i++) {
+                        LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
+                                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+                                heap[i].distance);
+                    }
+#endif
+                }
+
+                uint32_t currentPointerIndex = heap[0].currentPointerIndex;
+                if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
+
+                uint32_t lastPointerIndex = heap[0].lastPointerIndex;
+                if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
+
+                matchedCurrentBits.markBit(currentPointerIndex);
+                matchedLastBits.markBit(lastPointerIndex);
+
+                uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
+                mCurrentTouch.pointers[currentPointerIndex].id = id;
+                mCurrentTouch.idToIndex[id] = currentPointerIndex;
+                usedIdBits.markBit(id);
+
+#if DEBUG_POINTER_ASSIGNMENT
+                LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
+                        lastPointerIndex, currentPointerIndex, id, heap[0].distance);
+#endif
+                break;
+            }
+        }
+
+        // Assign fresh ids to new pointers.
+        if (currentPointerCount > lastPointerCount) {
+            for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
+                uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
+                uint32_t id = usedIdBits.firstUnmarkedBit();
+
+                mCurrentTouch.pointers[currentPointerIndex].id = id;
+                mCurrentTouch.idToIndex[id] = currentPointerIndex;
+                usedIdBits.markBit(id);
+
+#if DEBUG_POINTER_ASSIGNMENT
+                LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
+                        currentPointerIndex, id);
+#endif
+
+                if (--i == 0) break; // done
+                matchedCurrentBits.markBit(currentPointerIndex);
+            }
+        }
+
+        // Fix id bits.
+        mCurrentTouch.idBits = usedIdBits;
+    }
+}
+
+/* Special hack for devices that have bad screen data: if one of the
+ * points has moved more than a screen height from the last position,
+ * then drop it. */
+bool TouchInputMapper::applyBadTouchFilter() {
+    // This hack requires valid axis parameters.
+    if (! mRawAxes.y.valid) {
+        return false;
+    }
+
+    uint32_t pointerCount = mCurrentTouch.pointerCount;
+
+    // Nothing to do if there are no points.
+    if (pointerCount == 0) {
+        return false;
+    }
+
+    // Don't do anything if a finger is going down or up.  We run
+    // here before assigning pointer IDs, so there isn't a good
+    // way to do per-finger matching.
+    if (pointerCount != mLastTouch.pointerCount) {
+        return false;
+    }
+
+    // We consider a single movement across more than a 7/16 of
+    // the long size of the screen to be bad.  This was a magic value
+    // determined by looking at the maximum distance it is feasible
+    // to actually move in one sample.
+    int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16;
+
+    // XXX The original code in InputDevice.java included commented out
+    //     code for testing the X axis.  Note that when we drop a point
+    //     we don't actually restore the old X either.  Strange.
+    //     The old code also tries to track when bad points were previously
+    //     detected but it turns out that due to the placement of a "break"
+    //     at the end of the loop, we never set mDroppedBadPoint to true
+    //     so it is effectively dead code.
+    // Need to figure out if the old code is busted or just overcomplicated
+    // but working as intended.
+
+    // Look through all new points and see if any are farther than
+    // acceptable from all previous points.
+    for (uint32_t i = pointerCount; i-- > 0; ) {
+        int32_t y = mCurrentTouch.pointers[i].y;
+        int32_t closestY = INT_MAX;
+        int32_t closestDeltaY = 0;
+
+#if DEBUG_HACKS
+        LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y);
+#endif
+
+        for (uint32_t j = pointerCount; j-- > 0; ) {
+            int32_t lastY = mLastTouch.pointers[j].y;
+            int32_t deltaY = abs(y - lastY);
+
+#if DEBUG_HACKS
+            LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d",
+                    j, lastY, deltaY);
+#endif
+
+            if (deltaY < maxDeltaY) {
+                goto SkipSufficientlyClosePoint;
+            }
+            if (deltaY < closestDeltaY) {
+                closestDeltaY = deltaY;
+                closestY = lastY;
+            }
+        }
+
+        // Must not have found a close enough match.
+#if DEBUG_HACKS
+        LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d",
+                i, y, closestY, closestDeltaY, maxDeltaY);
+#endif
+
+        mCurrentTouch.pointers[i].y = closestY;
+        return true; // XXX original code only corrects one point
+
+    SkipSufficientlyClosePoint: ;
+    }
+
+    // No change.
+    return false;
+}
+
+/* Special hack for devices that have bad screen data: drop points where
+ * the coordinate value for one axis has jumped to the other pointer's location.
+ */
+bool TouchInputMapper::applyJumpyTouchFilter() {
+    // This hack requires valid axis parameters.
+    if (! mRawAxes.y.valid) {
+        return false;
+    }
+
+    uint32_t pointerCount = mCurrentTouch.pointerCount;
+    if (mLastTouch.pointerCount != pointerCount) {
+#if DEBUG_HACKS
+        LOGD("JumpyTouchFilter: Different pointer count %d -> %d",
+                mLastTouch.pointerCount, pointerCount);
+        for (uint32_t i = 0; i < pointerCount; i++) {
+            LOGD("  Pointer %d (%d, %d)", i,
+                    mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
+        }
+#endif
+
+        if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
+            if (mLastTouch.pointerCount == 1 && pointerCount == 2) {
+                // Just drop the first few events going from 1 to 2 pointers.
+                // They're bad often enough that they're not worth considering.
+                mCurrentTouch.pointerCount = 1;
+                mJumpyTouchFilter.jumpyPointsDropped += 1;
+
+#if DEBUG_HACKS
+                LOGD("JumpyTouchFilter: Pointer 2 dropped");
+#endif
+                return true;
+            } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) {
+                // The event when we go from 2 -> 1 tends to be messed up too
+                mCurrentTouch.pointerCount = 2;
+                mCurrentTouch.pointers[0] = mLastTouch.pointers[0];
+                mCurrentTouch.pointers[1] = mLastTouch.pointers[1];
+                mJumpyTouchFilter.jumpyPointsDropped += 1;
+
+#if DEBUG_HACKS
+                for (int32_t i = 0; i < 2; i++) {
+                    LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i,
+                            mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
+                }
+#endif
+                return true;
+            }
+        }
+        // Reset jumpy points dropped on other transitions or if limit exceeded.
+        mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+#if DEBUG_HACKS
+        LOGD("JumpyTouchFilter: Transition - drop limit reset");
+#endif
+        return false;
+    }
+
+    // We have the same number of pointers as last time.
+    // A 'jumpy' point is one where the coordinate value for one axis
+    // has jumped to the other pointer's location. No need to do anything
+    // else if we only have one pointer.
+    if (pointerCount < 2) {
+        return false;
+    }
+
+    if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
+        int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
+
+        // We only replace the single worst jumpy point as characterized by pointer distance
+        // in a single axis.
+        int32_t badPointerIndex = -1;
+        int32_t badPointerReplacementIndex = -1;
+        int32_t badPointerDistance = INT_MIN; // distance to be corrected
+
+        for (uint32_t i = pointerCount; i-- > 0; ) {
+            int32_t x = mCurrentTouch.pointers[i].x;
+            int32_t y = mCurrentTouch.pointers[i].y;
+
+#if DEBUG_HACKS
+            LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y);
+#endif
+
+            // Check if a touch point is too close to another's coordinates
+            bool dropX = false, dropY = false;
+            for (uint32_t j = 0; j < pointerCount; j++) {
+                if (i == j) {
+                    continue;
+                }
+
+                if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) {
+                    dropX = true;
+                    break;
+                }
+
+                if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) {
+                    dropY = true;
+                    break;
+                }
+            }
+            if (! dropX && ! dropY) {
+                continue; // not jumpy
+            }
+
+            // Find a replacement candidate by comparing with older points on the
+            // complementary (non-jumpy) axis.
+            int32_t distance = INT_MIN; // distance to be corrected
+            int32_t replacementIndex = -1;
+
+            if (dropX) {
+                // X looks too close.  Find an older replacement point with a close Y.
+                int32_t smallestDeltaY = INT_MAX;
+                for (uint32_t j = 0; j < pointerCount; j++) {
+                    int32_t deltaY = abs(y - mLastTouch.pointers[j].y);
+                    if (deltaY < smallestDeltaY) {
+                        smallestDeltaY = deltaY;
+                        replacementIndex = j;
+                    }
+                }
+                distance = abs(x - mLastTouch.pointers[replacementIndex].x);
+            } else {
+                // Y looks too close.  Find an older replacement point with a close X.
+                int32_t smallestDeltaX = INT_MAX;
+                for (uint32_t j = 0; j < pointerCount; j++) {
+                    int32_t deltaX = abs(x - mLastTouch.pointers[j].x);
+                    if (deltaX < smallestDeltaX) {
+                        smallestDeltaX = deltaX;
+                        replacementIndex = j;
+                    }
+                }
+                distance = abs(y - mLastTouch.pointers[replacementIndex].y);
+            }
+
+            // If replacing this pointer would correct a worse error than the previous ones
+            // considered, then use this replacement instead.
+            if (distance > badPointerDistance) {
+                badPointerIndex = i;
+                badPointerReplacementIndex = replacementIndex;
+                badPointerDistance = distance;
+            }
+        }
+
+        // Correct the jumpy pointer if one was found.
+        if (badPointerIndex >= 0) {
+#if DEBUG_HACKS
+            LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)",
+                    badPointerIndex,
+                    mLastTouch.pointers[badPointerReplacementIndex].x,
+                    mLastTouch.pointers[badPointerReplacementIndex].y);
+#endif
+
+            mCurrentTouch.pointers[badPointerIndex].x =
+                    mLastTouch.pointers[badPointerReplacementIndex].x;
+            mCurrentTouch.pointers[badPointerIndex].y =
+                    mLastTouch.pointers[badPointerReplacementIndex].y;
+            mJumpyTouchFilter.jumpyPointsDropped += 1;
+            return true;
+        }
+    }
+
+    mJumpyTouchFilter.jumpyPointsDropped = 0;
+    return false;
+}
+
+/* Special hack for devices that have bad screen data: aggregate and
+ * compute averages of the coordinate data, to reduce the amount of
+ * jitter seen by applications. */
+void TouchInputMapper::applyAveragingTouchFilter() {
+    for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) {
+        uint32_t id = mCurrentTouch.pointers[currentIndex].id;
+        int32_t x = mCurrentTouch.pointers[currentIndex].x;
+        int32_t y = mCurrentTouch.pointers[currentIndex].y;
+        int32_t pressure;
+        switch (mCalibration.pressureSource) {
+        case Calibration::PRESSURE_SOURCE_PRESSURE:
+            pressure = mCurrentTouch.pointers[currentIndex].pressure;
+            break;
+        case Calibration::PRESSURE_SOURCE_TOUCH:
+            pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
+            break;
+        default:
+            pressure = 1;
+            break;
+        }
+
+        if (mLastTouch.idBits.hasBit(id)) {
+            // Pointer was down before and is still down now.
+            // Compute average over history trace.
+            uint32_t start = mAveragingTouchFilter.historyStart[id];
+            uint32_t end = mAveragingTouchFilter.historyEnd[id];
+
+            int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x;
+            int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y;
+            uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
+
+#if DEBUG_HACKS
+            LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld",
+                    id, distance);
+#endif
+
+            if (distance < AVERAGING_DISTANCE_LIMIT) {
+                // Increment end index in preparation for recording new historical data.
+                end += 1;
+                if (end > AVERAGING_HISTORY_SIZE) {
+                    end = 0;
+                }
+
+                // If the end index has looped back to the start index then we have filled
+                // the historical trace up to the desired size so we drop the historical
+                // data at the start of the trace.
+                if (end == start) {
+                    start += 1;
+                    if (start > AVERAGING_HISTORY_SIZE) {
+                        start = 0;
+                    }
+                }
+
+                // Add the raw data to the historical trace.
+                mAveragingTouchFilter.historyStart[id] = start;
+                mAveragingTouchFilter.historyEnd[id] = end;
+                mAveragingTouchFilter.historyData[end].pointers[id].x = x;
+                mAveragingTouchFilter.historyData[end].pointers[id].y = y;
+                mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure;
+
+                // Average over all historical positions in the trace by total pressure.
+                int32_t averagedX = 0;
+                int32_t averagedY = 0;
+                int32_t totalPressure = 0;
+                for (;;) {
+                    int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x;
+                    int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y;
+                    int32_t historicalPressure = mAveragingTouchFilter.historyData[start]
+                            .pointers[id].pressure;
+
+                    averagedX += historicalX * historicalPressure;
+                    averagedY += historicalY * historicalPressure;
+                    totalPressure += historicalPressure;
+
+                    if (start == end) {
+                        break;
+                    }
+
+                    start += 1;
+                    if (start > AVERAGING_HISTORY_SIZE) {
+                        start = 0;
+                    }
+                }
+
+                if (totalPressure != 0) {
+                    averagedX /= totalPressure;
+                    averagedY /= totalPressure;
+
+#if DEBUG_HACKS
+                    LOGD("AveragingTouchFilter: Pointer id %d - "
+                            "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
+                            averagedX, averagedY);
+#endif
+
+                    mCurrentTouch.pointers[currentIndex].x = averagedX;
+                    mCurrentTouch.pointers[currentIndex].y = averagedY;
+                }
+            } else {
+#if DEBUG_HACKS
+                LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
+#endif
+            }
+        } else {
+#if DEBUG_HACKS
+            LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id);
+#endif
+        }
+
+        // Reset pointer history.
+        mAveragingTouchFilter.historyStart[id] = 0;
+        mAveragingTouchFilter.historyEnd[id] = 0;
+        mAveragingTouchFilter.historyData[0].pointers[id].x = x;
+        mAveragingTouchFilter.historyData[0].pointers[id].y = y;
+        mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure;
+    }
+}
+
+int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
+            return AKEY_STATE_VIRTUAL;
+        }
+
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+            if (virtualKey.keyCode == keyCode) {
+                return AKEY_STATE_UP;
+            }
+        }
+    } // release lock
+
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
+            return AKEY_STATE_VIRTUAL;
+        }
+
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+            if (virtualKey.scanCode == scanCode) {
+                return AKEY_STATE_UP;
+            }
+        }
+    } // release lock
+
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+
+            for (size_t i = 0; i < numCodes; i++) {
+                if (virtualKey.keyCode == keyCodes[i]) {
+                    outFlags[i] = 1;
+                }
+            }
+        }
+    } // release lock
+
+    return true;
+}
+
+
+// --- SingleTouchInputMapper ---
+
+SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        TouchInputMapper(device, associatedDisplayId) {
+    initialize();
+}
+
+SingleTouchInputMapper::~SingleTouchInputMapper() {
+}
+
+void SingleTouchInputMapper::initialize() {
+    mAccumulator.clear();
+
+    mDown = false;
+    mX = 0;
+    mY = 0;
+    mPressure = 0; // default to 0 for devices that don't report pressure
+    mToolWidth = 0; // default to 0 for devices that don't report tool width
+}
+
+void SingleTouchInputMapper::reset() {
+    TouchInputMapper::reset();
+
+    initialize();
+ }
+
+void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY:
+        switch (rawEvent->scanCode) {
+        case BTN_TOUCH:
+            mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
+            mAccumulator.btnTouch = rawEvent->value != 0;
+            // Don't sync immediately.  Wait until the next SYN_REPORT since we might
+            // not have received valid position information yet.  This logic assumes that
+            // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet.
+            break;
+        }
+        break;
+
+    case EV_ABS:
+        switch (rawEvent->scanCode) {
+        case ABS_X:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_X;
+            mAccumulator.absX = rawEvent->value;
+            break;
+        case ABS_Y:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
+            mAccumulator.absY = rawEvent->value;
+            break;
+        case ABS_PRESSURE:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE;
+            mAccumulator.absPressure = rawEvent->value;
+            break;
+        case ABS_TOOL_WIDTH:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH;
+            mAccumulator.absToolWidth = rawEvent->value;
+            break;
+        }
+        break;
+
+    case EV_SYN:
+        switch (rawEvent->scanCode) {
+        case SYN_REPORT:
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+    }
+}
+
+void SingleTouchInputMapper::sync(nsecs_t when) {
+    uint32_t fields = mAccumulator.fields;
+    if (fields == 0) {
+        return; // no new state changes, so nothing to do
+    }
+
+    if (fields & Accumulator::FIELD_BTN_TOUCH) {
+        mDown = mAccumulator.btnTouch;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_X) {
+        mX = mAccumulator.absX;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_Y) {
+        mY = mAccumulator.absY;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_PRESSURE) {
+        mPressure = mAccumulator.absPressure;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
+        mToolWidth = mAccumulator.absToolWidth;
+    }
+
+    mCurrentTouch.clear();
+
+    if (mDown) {
+        mCurrentTouch.pointerCount = 1;
+        mCurrentTouch.pointers[0].id = 0;
+        mCurrentTouch.pointers[0].x = mX;
+        mCurrentTouch.pointers[0].y = mY;
+        mCurrentTouch.pointers[0].pressure = mPressure;
+        mCurrentTouch.pointers[0].touchMajor = 0;
+        mCurrentTouch.pointers[0].touchMinor = 0;
+        mCurrentTouch.pointers[0].toolMajor = mToolWidth;
+        mCurrentTouch.pointers[0].toolMinor = mToolWidth;
+        mCurrentTouch.pointers[0].orientation = 0;
+        mCurrentTouch.idToIndex[0] = 0;
+        mCurrentTouch.idBits.markBit(0);
+    }
+
+    syncTouch(when, true);
+
+    mAccumulator.clear();
+}
+
+void SingleTouchInputMapper::configureRawAxes() {
+    TouchInputMapper::configureRawAxes();
+
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
+}
+
+
+// --- MultiTouchInputMapper ---
+
+MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        TouchInputMapper(device, associatedDisplayId) {
+    initialize();
+}
+
+MultiTouchInputMapper::~MultiTouchInputMapper() {
+}
+
+void MultiTouchInputMapper::initialize() {
+    mAccumulator.clear();
+}
+
+void MultiTouchInputMapper::reset() {
+    TouchInputMapper::reset();
+
+    initialize();
+}
+
+void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_ABS: {
+        uint32_t pointerIndex = mAccumulator.pointerCount;
+        Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex];
+
+        switch (rawEvent->scanCode) {
+        case ABS_MT_POSITION_X:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X;
+            pointer->absMTPositionX = rawEvent->value;
+            break;
+        case ABS_MT_POSITION_Y:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y;
+            pointer->absMTPositionY = rawEvent->value;
+            break;
+        case ABS_MT_TOUCH_MAJOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
+            pointer->absMTTouchMajor = rawEvent->value;
+            break;
+        case ABS_MT_TOUCH_MINOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR;
+            pointer->absMTTouchMinor = rawEvent->value;
+            break;
+        case ABS_MT_WIDTH_MAJOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
+            pointer->absMTWidthMajor = rawEvent->value;
+            break;
+        case ABS_MT_WIDTH_MINOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR;
+            pointer->absMTWidthMinor = rawEvent->value;
+            break;
+        case ABS_MT_ORIENTATION:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION;
+            pointer->absMTOrientation = rawEvent->value;
+            break;
+        case ABS_MT_TRACKING_ID:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
+            pointer->absMTTrackingId = rawEvent->value;
+            break;
+        case ABS_MT_PRESSURE:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
+            pointer->absMTPressure = rawEvent->value;
+            break;
+        }
+        break;
+    }
+
+    case EV_SYN:
+        switch (rawEvent->scanCode) {
+        case SYN_MT_REPORT: {
+            // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
+            uint32_t pointerIndex = mAccumulator.pointerCount;
+
+            if (mAccumulator.pointers[pointerIndex].fields) {
+                if (pointerIndex == MAX_POINTERS) {
+                    LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
+                            MAX_POINTERS);
+                } else {
+                    pointerIndex += 1;
+                    mAccumulator.pointerCount = pointerIndex;
+                }
+            }
+
+            mAccumulator.pointers[pointerIndex].clear();
+            break;
+        }
+
+        case SYN_REPORT:
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+    }
+}
+
+void MultiTouchInputMapper::sync(nsecs_t when) {
+    static const uint32_t REQUIRED_FIELDS =
+            Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
+
+    uint32_t inCount = mAccumulator.pointerCount;
+    uint32_t outCount = 0;
+    bool havePointerIds = true;
+
+    mCurrentTouch.clear();
+
+    for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
+        const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex];
+        uint32_t fields = inPointer.fields;
+
+        if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
+            // Some drivers send empty MT sync packets without X / Y to indicate a pointer up.
+            // Drop this finger.
+            continue;
+        }
+
+        PointerData& outPointer = mCurrentTouch.pointers[outCount];
+        outPointer.x = inPointer.absMTPositionX;
+        outPointer.y = inPointer.absMTPositionY;
+
+        if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
+            if (inPointer.absMTPressure <= 0) {
+                // Some devices send sync packets with X / Y but with a 0 presure to indicate
+                // a pointer up.  Drop this finger.
+                continue;
+            }
+            outPointer.pressure = inPointer.absMTPressure;
+        } else {
+            // Default pressure to 0 if absent.
+            outPointer.pressure = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
+            if (inPointer.absMTTouchMajor <= 0) {
+                // Some devices send sync packets with X / Y but with a 0 touch major to indicate
+                // a pointer going up.  Drop this finger.
+                continue;
+            }
+            outPointer.touchMajor = inPointer.absMTTouchMajor;
+        } else {
+            // Default touch area to 0 if absent.
+            outPointer.touchMajor = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
+            outPointer.touchMinor = inPointer.absMTTouchMinor;
+        } else {
+            // Assume touch area is circular.
+            outPointer.touchMinor = outPointer.touchMajor;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
+            outPointer.toolMajor = inPointer.absMTWidthMajor;
+        } else {
+            // Default tool area to 0 if absent.
+            outPointer.toolMajor = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
+            outPointer.toolMinor = inPointer.absMTWidthMinor;
+        } else {
+            // Assume tool area is circular.
+            outPointer.toolMinor = outPointer.toolMajor;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
+            outPointer.orientation = inPointer.absMTOrientation;
+        } else {
+            // Default orientation to vertical if absent.
+            outPointer.orientation = 0;
+        }
+
+        // Assign pointer id using tracking id if available.
+        if (havePointerIds) {
+            if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
+                uint32_t id = uint32_t(inPointer.absMTTrackingId);
+
+                if (id > MAX_POINTER_ID) {
+#if DEBUG_POINTERS
+                    LOGD("Pointers: Ignoring driver provided pointer id %d because "
+                            "it is larger than max supported id %d for optimizations",
+                            id, MAX_POINTER_ID);
+#endif
+                    havePointerIds = false;
+                }
+                else {
+                    outPointer.id = id;
+                    mCurrentTouch.idToIndex[id] = outCount;
+                    mCurrentTouch.idBits.markBit(id);
+                }
+            } else {
+                havePointerIds = false;
+            }
+        }
+
+        outCount += 1;
+    }
+
+    mCurrentTouch.pointerCount = outCount;
+
+    syncTouch(when, havePointerIds);
+
+    mAccumulator.clear();
+}
+
+void MultiTouchInputMapper::configureRawAxes() {
+    TouchInputMapper::configureRawAxes();
+
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
+}
+
+
+} // namespace android
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
new file mode 100644
index 0000000..4c402dc
--- /dev/null
+++ b/libs/ui/InputTransport.cpp
@@ -0,0 +1,695 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// Provides a shared memory transport for input events.
+//
+#define LOG_TAG "InputTransport"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages about channel signalling (send signal, receive signal)
+#define DEBUG_CHANNEL_SIGNALS 0
+
+// Log debug messages whenever InputChannel objects are created/destroyed
+#define DEBUG_CHANNEL_LIFECYCLE 0
+
+// Log debug messages about transport actions (initialize, reset, publish, ...)
+#define DEBUG_TRANSPORT_ACTIONS 0
+
+
+#include <cutils/ashmem.h>
+#include <cutils/log.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <ui/InputTransport.h>
+#include <unistd.h>
+
+namespace android {
+
+// Must be at least sizeof(InputMessage) + sufficient space for pointer data
+static const int DEFAULT_MESSAGE_BUFFER_SIZE = 16384;
+
+// Signal sent by the producer to the consumer to inform it that a new message is
+// available to be consumed in the shared memory buffer.
+static const char INPUT_SIGNAL_DISPATCH = 'D';
+
+// Signal sent by the consumer to the producer to inform it that it has finished
+// consuming the most recent message.
+static const char INPUT_SIGNAL_FINISHED = 'f';
+
+
+// --- InputChannel ---
+
+InputChannel::InputChannel(const String8& name, int32_t ashmemFd, int32_t receivePipeFd,
+        int32_t sendPipeFd) :
+        mName(name), mAshmemFd(ashmemFd), mReceivePipeFd(receivePipeFd), mSendPipeFd(sendPipeFd) {
+#if DEBUG_CHANNEL_LIFECYCLE
+    LOGD("Input channel constructed: name='%s', ashmemFd=%d, receivePipeFd=%d, sendPipeFd=%d",
+            mName.string(), ashmemFd, receivePipeFd, sendPipeFd);
+#endif
+
+    int result = fcntl(mReceivePipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make receive pipe "
+            "non-blocking.  errno=%d", mName.string(), errno);
+
+    result = fcntl(mSendPipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "channel '%s' ~ Could not make send pipe "
+            "non-blocking.  errno=%d", mName.string(), errno);
+}
+
+InputChannel::~InputChannel() {
+#if DEBUG_CHANNEL_LIFECYCLE
+    LOGD("Input channel destroyed: name='%s', ashmemFd=%d, receivePipeFd=%d, sendPipeFd=%d",
+            mName.string(), mAshmemFd, mReceivePipeFd, mSendPipeFd);
+#endif
+
+    ::close(mAshmemFd);
+    ::close(mReceivePipeFd);
+    ::close(mSendPipeFd);
+}
+
+status_t InputChannel::openInputChannelPair(const String8& name,
+        sp<InputChannel>& outServerChannel, sp<InputChannel>& outClientChannel) {
+    status_t result;
+
+    int serverAshmemFd = ashmem_create_region(name.string(), DEFAULT_MESSAGE_BUFFER_SIZE);
+    if (serverAshmemFd < 0) {
+        result = -errno;
+        LOGE("channel '%s' ~ Could not create shared memory region. errno=%d",
+                name.string(), errno);
+    } else {
+        result = ashmem_set_prot_region(serverAshmemFd, PROT_READ | PROT_WRITE);
+        if (result < 0) {
+            LOGE("channel '%s' ~ Error %d trying to set protection of ashmem fd %d.",
+                    name.string(), result, serverAshmemFd);
+        } else {
+            // Dup the file descriptor because the server and client input channel objects that
+            // are returned may have different lifetimes but they share the same shared memory region.
+            int clientAshmemFd;
+            clientAshmemFd = dup(serverAshmemFd);
+            if (clientAshmemFd < 0) {
+                result = -errno;
+                LOGE("channel '%s' ~ Could not dup() shared memory region fd. errno=%d",
+                        name.string(), errno);
+            } else {
+                int forward[2];
+                if (pipe(forward)) {
+                    result = -errno;
+                    LOGE("channel '%s' ~ Could not create forward pipe.  errno=%d",
+                            name.string(), errno);
+                } else {
+                    int reverse[2];
+                    if (pipe(reverse)) {
+                        result = -errno;
+                        LOGE("channel '%s' ~ Could not create reverse pipe.  errno=%d",
+                                name.string(), errno);
+                    } else {
+                        String8 serverChannelName = name;
+                        serverChannelName.append(" (server)");
+                        outServerChannel = new InputChannel(serverChannelName,
+                                serverAshmemFd, reverse[0], forward[1]);
+
+                        String8 clientChannelName = name;
+                        clientChannelName.append(" (client)");
+                        outClientChannel = new InputChannel(clientChannelName,
+                                clientAshmemFd, forward[0], reverse[1]);
+                        return OK;
+                    }
+                    ::close(forward[0]);
+                    ::close(forward[1]);
+                }
+                ::close(clientAshmemFd);
+            }
+        }
+        ::close(serverAshmemFd);
+    }
+
+    outServerChannel.clear();
+    outClientChannel.clear();
+    return result;
+}
+
+status_t InputChannel::sendSignal(char signal) {
+    ssize_t nWrite = ::write(mSendPipeFd, & signal, 1);
+
+    if (nWrite == 1) {
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ sent signal '%c'", mName.string(), signal);
+#endif
+        return OK;
+    }
+
+#if DEBUG_CHANNEL_SIGNALS
+    LOGD("channel '%s' ~ error sending signal '%c', errno=%d", mName.string(), signal, errno);
+#endif
+    return -errno;
+}
+
+status_t InputChannel::receiveSignal(char* outSignal) {
+    ssize_t nRead = ::read(mReceivePipeFd, outSignal, 1);
+    if (nRead == 1) {
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ received signal '%c'", mName.string(), *outSignal);
+#endif
+        return OK;
+    }
+
+    if (nRead == 0) { // check for EOF
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ receive signal failed because peer was closed", mName.string());
+#endif
+        return DEAD_OBJECT;
+    }
+
+    if (errno == EAGAIN) {
+#if DEBUG_CHANNEL_SIGNALS
+        LOGD("channel '%s' ~ receive signal failed because no signal available", mName.string());
+#endif
+        return WOULD_BLOCK;
+    }
+
+#if DEBUG_CHANNEL_SIGNALS
+    LOGD("channel '%s' ~ receive signal failed, errno=%d", mName.string(), errno);
+#endif
+    return -errno;
+}
+
+
+// --- InputPublisher ---
+
+InputPublisher::InputPublisher(const sp<InputChannel>& channel) :
+        mChannel(channel), mSharedMessage(NULL),
+        mPinned(false), mSemaphoreInitialized(false), mWasDispatched(false),
+        mMotionEventSampleDataTail(NULL) {
+}
+
+InputPublisher::~InputPublisher() {
+    reset();
+
+    if (mSharedMessage) {
+        munmap(mSharedMessage, mAshmemSize);
+    }
+}
+
+status_t InputPublisher::initialize() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ initialize",
+            mChannel->getName().string());
+#endif
+
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_get_size_region(ashmemFd);
+    if (result < 0) {
+        LOGE("channel '%s' publisher ~ Error %d getting size of ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+    mAshmemSize = (size_t) result;
+
+    mSharedMessage = static_cast<InputMessage*>(mmap(NULL, mAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0));
+    if (! mSharedMessage) {
+        LOGE("channel '%s' publisher ~ mmap failed on ashmem fd %d.",
+                mChannel->getName().string(), ashmemFd);
+        return NO_MEMORY;
+    }
+
+    mPinned = true;
+    mSharedMessage->consumed = false;
+
+    return reset();
+}
+
+status_t InputPublisher::reset() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ reset",
+        mChannel->getName().string());
+#endif
+
+    if (mPinned) {
+        // Destroy the semaphore since we are about to unpin the memory region that contains it.
+        int result;
+        if (mSemaphoreInitialized) {
+            if (mSharedMessage->consumed) {
+                result = sem_post(& mSharedMessage->semaphore);
+                if (result < 0) {
+                    LOGE("channel '%s' publisher ~ Error %d in sem_post.",
+                            mChannel->getName().string(), errno);
+                    return UNKNOWN_ERROR;
+                }
+            }
+
+            result = sem_destroy(& mSharedMessage->semaphore);
+            if (result < 0) {
+                LOGE("channel '%s' publisher ~ Error %d in sem_destroy.",
+                        mChannel->getName().string(), errno);
+                return UNKNOWN_ERROR;
+            }
+
+            mSemaphoreInitialized = false;
+        }
+
+        // Unpin the region since we no longer care about its contents.
+        int ashmemFd = mChannel->getAshmemFd();
+        result = ashmem_unpin_region(ashmemFd, 0, 0);
+        if (result < 0) {
+            LOGE("channel '%s' publisher ~ Error %d unpinning ashmem fd %d.",
+                    mChannel->getName().string(), result, ashmemFd);
+            return UNKNOWN_ERROR;
+        }
+
+        mPinned = false;
+    }
+
+    mMotionEventSampleDataTail = NULL;
+    mWasDispatched = false;
+    return OK;
+}
+
+status_t InputPublisher::publishInputEvent(
+        int32_t type,
+        int32_t deviceId,
+        int32_t source) {
+    if (mPinned) {
+        LOGE("channel '%s' publisher ~ Attempted to publish a new event but publisher has "
+                "not yet been reset.", mChannel->getName().string());
+        return INVALID_OPERATION;
+    }
+
+    // Pin the region.
+    // We do not check for ASHMEM_NOT_PURGED because we don't care about the previous
+    // contents of the buffer so it does not matter whether it was purged in the meantime.
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_pin_region(ashmemFd, 0, 0);
+    if (result < 0) {
+        LOGE("channel '%s' publisher ~ Error %d pinning ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+
+    mPinned = true;
+
+    result = sem_init(& mSharedMessage->semaphore, 1, 1);
+    if (result < 0) {
+        LOGE("channel '%s' publisher ~ Error %d in sem_init.",
+                mChannel->getName().string(), errno);
+        return UNKNOWN_ERROR;
+    }
+
+    mSemaphoreInitialized = true;
+
+    mSharedMessage->consumed = false;
+    mSharedMessage->type = type;
+    mSharedMessage->deviceId = deviceId;
+    mSharedMessage->source = source;
+    return OK;
+}
+
+status_t InputPublisher::publishKeyEvent(
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t keyCode,
+        int32_t scanCode,
+        int32_t metaState,
+        int32_t repeatCount,
+        nsecs_t downTime,
+        nsecs_t eventTime) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ publishKeyEvent: deviceId=%d, source=0x%x, "
+            "action=0x%x, flags=0x%x, keyCode=%d, scanCode=%d, metaState=0x%x, repeatCount=%d,"
+            "downTime=%lld, eventTime=%lld",
+            mChannel->getName().string(),
+            deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
+            downTime, eventTime);
+#endif
+
+    status_t result = publishInputEvent(AINPUT_EVENT_TYPE_KEY, deviceId, source);
+    if (result < 0) {
+        return result;
+    }
+
+    mSharedMessage->key.action = action;
+    mSharedMessage->key.flags = flags;
+    mSharedMessage->key.keyCode = keyCode;
+    mSharedMessage->key.scanCode = scanCode;
+    mSharedMessage->key.metaState = metaState;
+    mSharedMessage->key.repeatCount = repeatCount;
+    mSharedMessage->key.downTime = downTime;
+    mSharedMessage->key.eventTime = eventTime;
+    return OK;
+}
+
+status_t InputPublisher::publishMotionEvent(
+        int32_t deviceId,
+        int32_t source,
+        int32_t action,
+        int32_t flags,
+        int32_t edgeFlags,
+        int32_t metaState,
+        float xOffset,
+        float yOffset,
+        float xPrecision,
+        float yPrecision,
+        nsecs_t downTime,
+        nsecs_t eventTime,
+        size_t pointerCount,
+        const int32_t* pointerIds,
+        const PointerCoords* pointerCoords) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ publishMotionEvent: deviceId=%d, source=0x%x, "
+            "action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, xOffset=%f, yOffset=%f, "
+            "xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
+            "pointerCount=%d",
+            mChannel->getName().string(),
+            deviceId, source, action, flags, edgeFlags, metaState, xOffset, yOffset,
+            xPrecision, yPrecision, downTime, eventTime, pointerCount);
+#endif
+
+    if (pointerCount > MAX_POINTERS || pointerCount < 1) {
+        LOGE("channel '%s' publisher ~ Invalid number of pointers provided: %d.",
+                mChannel->getName().string(), pointerCount);
+        return BAD_VALUE;
+    }
+
+    status_t result = publishInputEvent(AINPUT_EVENT_TYPE_MOTION, deviceId, source);
+    if (result < 0) {
+        return result;
+    }
+
+    mSharedMessage->motion.action = action;
+    mSharedMessage->motion.flags = flags;
+    mSharedMessage->motion.edgeFlags = edgeFlags;
+    mSharedMessage->motion.metaState = metaState;
+    mSharedMessage->motion.xOffset = xOffset;
+    mSharedMessage->motion.yOffset = yOffset;
+    mSharedMessage->motion.xPrecision = xPrecision;
+    mSharedMessage->motion.yPrecision = yPrecision;
+    mSharedMessage->motion.downTime = downTime;
+    mSharedMessage->motion.pointerCount = pointerCount;
+
+    mSharedMessage->motion.sampleCount = 1;
+    mSharedMessage->motion.sampleData[0].eventTime = eventTime;
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        mSharedMessage->motion.pointerIds[i] = pointerIds[i];
+        mSharedMessage->motion.sampleData[0].coords[i] = pointerCoords[i];
+    }
+
+    // Cache essential information about the motion event to ensure that a malicious consumer
+    // cannot confuse the publisher by modifying the contents of the shared memory buffer while
+    // it is being updated.
+    if (action == AMOTION_EVENT_ACTION_MOVE) {
+        mMotionEventPointerCount = pointerCount;
+        mMotionEventSampleDataStride = InputMessage::sampleDataStride(pointerCount);
+        mMotionEventSampleDataTail = InputMessage::sampleDataPtrIncrement(
+                mSharedMessage->motion.sampleData, mMotionEventSampleDataStride);
+    } else {
+        mMotionEventSampleDataTail = NULL;
+    }
+    return OK;
+}
+
+status_t InputPublisher::appendMotionSample(
+        nsecs_t eventTime,
+        const PointerCoords* pointerCoords) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ appendMotionSample: eventTime=%lld",
+            mChannel->getName().string(), eventTime);
+#endif
+
+    if (! mPinned || ! mMotionEventSampleDataTail) {
+        LOGE("channel '%s' publisher ~ Cannot append motion sample because there is no current "
+                "AMOTION_EVENT_ACTION_MOVE event.", mChannel->getName().string());
+        return INVALID_OPERATION;
+    }
+
+    InputMessage::SampleData* newTail = InputMessage::sampleDataPtrIncrement(
+            mMotionEventSampleDataTail, mMotionEventSampleDataStride);
+    size_t newBytesUsed = reinterpret_cast<char*>(newTail) -
+            reinterpret_cast<char*>(mSharedMessage);
+
+    if (newBytesUsed > mAshmemSize) {
+#if DEBUG_TRANSPORT_ACTIONS
+        LOGD("channel '%s' publisher ~ Cannot append motion sample because the shared memory "
+                "buffer is full.  Buffer size: %d bytes, pointers: %d, samples: %d",
+                mChannel->getName().string(),
+                mAshmemSize, mMotionEventPointerCount, mSharedMessage->motion.sampleCount);
+#endif
+        return NO_MEMORY;
+    }
+
+    int result;
+    if (mWasDispatched) {
+        result = sem_trywait(& mSharedMessage->semaphore);
+        if (result < 0) {
+            if (errno == EAGAIN) {
+                // Only possible source of contention is the consumer having consumed (or being in the
+                // process of consuming) the message and left the semaphore count at 0.
+#if DEBUG_TRANSPORT_ACTIONS
+                LOGD("channel '%s' publisher ~ Cannot append motion sample because the message has "
+                        "already been consumed.", mChannel->getName().string());
+#endif
+                return FAILED_TRANSACTION;
+            } else {
+                LOGE("channel '%s' publisher ~ Error %d in sem_trywait.",
+                        mChannel->getName().string(), errno);
+                return UNKNOWN_ERROR;
+            }
+        }
+    }
+
+    mMotionEventSampleDataTail->eventTime = eventTime;
+    for (size_t i = 0; i < mMotionEventPointerCount; i++) {
+        mMotionEventSampleDataTail->coords[i] = pointerCoords[i];
+    }
+    mMotionEventSampleDataTail = newTail;
+
+    mSharedMessage->motion.sampleCount += 1;
+
+    if (mWasDispatched) {
+        result = sem_post(& mSharedMessage->semaphore);
+        if (result < 0) {
+            LOGE("channel '%s' publisher ~ Error %d in sem_post.",
+                    mChannel->getName().string(), errno);
+            return UNKNOWN_ERROR;
+        }
+    }
+    return OK;
+}
+
+status_t InputPublisher::sendDispatchSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ sendDispatchSignal",
+            mChannel->getName().string());
+#endif
+
+    mWasDispatched = true;
+    return mChannel->sendSignal(INPUT_SIGNAL_DISPATCH);
+}
+
+status_t InputPublisher::receiveFinishedSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' publisher ~ receiveFinishedSignal",
+            mChannel->getName().string());
+#endif
+
+    char signal;
+    status_t result = mChannel->receiveSignal(& signal);
+    if (result) {
+        return result;
+    }
+    if (signal != INPUT_SIGNAL_FINISHED) {
+        LOGE("channel '%s' publisher ~ Received unexpected signal '%c' from consumer",
+                mChannel->getName().string(), signal);
+        return UNKNOWN_ERROR;
+    }
+    return OK;
+}
+
+// --- InputConsumer ---
+
+InputConsumer::InputConsumer(const sp<InputChannel>& channel) :
+        mChannel(channel), mSharedMessage(NULL) {
+}
+
+InputConsumer::~InputConsumer() {
+    if (mSharedMessage) {
+        munmap(mSharedMessage, mAshmemSize);
+    }
+}
+
+status_t InputConsumer::initialize() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ initialize",
+            mChannel->getName().string());
+#endif
+
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_get_size_region(ashmemFd);
+    if (result < 0) {
+        LOGE("channel '%s' consumer ~ Error %d getting size of ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+
+    mAshmemSize = (size_t) result;
+
+    mSharedMessage = static_cast<InputMessage*>(mmap(NULL, mAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, ashmemFd, 0));
+    if (! mSharedMessage) {
+        LOGE("channel '%s' consumer ~ mmap failed on ashmem fd %d.",
+                mChannel->getName().string(), ashmemFd);
+        return NO_MEMORY;
+    }
+
+    return OK;
+}
+
+status_t InputConsumer::consume(InputEventFactoryInterface* factory, InputEvent** outEvent) {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ consume",
+            mChannel->getName().string());
+#endif
+
+    *outEvent = NULL;
+
+    int ashmemFd = mChannel->getAshmemFd();
+    int result = ashmem_pin_region(ashmemFd, 0, 0);
+    if (result != ASHMEM_NOT_PURGED) {
+        if (result == ASHMEM_WAS_PURGED) {
+            LOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d because it was purged "
+                    "which probably indicates that the publisher and consumer are out of sync.",
+                    mChannel->getName().string(), result, ashmemFd);
+            return INVALID_OPERATION;
+        }
+
+        LOGE("channel '%s' consumer ~ Error %d pinning ashmem fd %d.",
+                mChannel->getName().string(), result, ashmemFd);
+        return UNKNOWN_ERROR;
+    }
+
+    if (mSharedMessage->consumed) {
+        LOGE("channel '%s' consumer ~ The current message has already been consumed.",
+                mChannel->getName().string());
+        return INVALID_OPERATION;
+    }
+
+    // Acquire but *never release* the semaphore.  Contention on the semaphore is used to signal
+    // to the publisher that the message has been consumed (or is in the process of being
+    // consumed).  Eventually the publisher will reinitialize the semaphore for the next message.
+    result = sem_wait(& mSharedMessage->semaphore);
+    if (result < 0) {
+        LOGE("channel '%s' consumer ~ Error %d in sem_wait.",
+                mChannel->getName().string(), errno);
+        return UNKNOWN_ERROR;
+    }
+
+    mSharedMessage->consumed = true;
+
+    switch (mSharedMessage->type) {
+    case AINPUT_EVENT_TYPE_KEY: {
+        KeyEvent* keyEvent = factory->createKeyEvent();
+        if (! keyEvent) return NO_MEMORY;
+
+        populateKeyEvent(keyEvent);
+
+        *outEvent = keyEvent;
+        break;
+    }
+
+    case AINPUT_EVENT_TYPE_MOTION: {
+        MotionEvent* motionEvent = factory->createMotionEvent();
+        if (! motionEvent) return NO_MEMORY;
+
+        populateMotionEvent(motionEvent);
+
+        *outEvent = motionEvent;
+        break;
+    }
+
+    default:
+        LOGE("channel '%s' consumer ~ Received message of unknown type %d",
+                mChannel->getName().string(), mSharedMessage->type);
+        return UNKNOWN_ERROR;
+    }
+
+    return OK;
+}
+
+status_t InputConsumer::sendFinishedSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ sendFinishedSignal",
+            mChannel->getName().string());
+#endif
+
+    return mChannel->sendSignal(INPUT_SIGNAL_FINISHED);
+}
+
+status_t InputConsumer::receiveDispatchSignal() {
+#if DEBUG_TRANSPORT_ACTIONS
+    LOGD("channel '%s' consumer ~ receiveDispatchSignal",
+            mChannel->getName().string());
+#endif
+
+    char signal;
+    status_t result = mChannel->receiveSignal(& signal);
+    if (result) {
+        return result;
+    }
+    if (signal != INPUT_SIGNAL_DISPATCH) {
+        LOGE("channel '%s' consumer ~ Received unexpected signal '%c' from publisher",
+                mChannel->getName().string(), signal);
+        return UNKNOWN_ERROR;
+    }
+    return OK;
+}
+
+void InputConsumer::populateKeyEvent(KeyEvent* keyEvent) const {
+    keyEvent->initialize(
+            mSharedMessage->deviceId,
+            mSharedMessage->source,
+            mSharedMessage->key.action,
+            mSharedMessage->key.flags,
+            mSharedMessage->key.keyCode,
+            mSharedMessage->key.scanCode,
+            mSharedMessage->key.metaState,
+            mSharedMessage->key.repeatCount,
+            mSharedMessage->key.downTime,
+            mSharedMessage->key.eventTime);
+}
+
+void InputConsumer::populateMotionEvent(MotionEvent* motionEvent) const {
+    motionEvent->initialize(
+            mSharedMessage->deviceId,
+            mSharedMessage->source,
+            mSharedMessage->motion.action,
+            mSharedMessage->motion.flags,
+            mSharedMessage->motion.edgeFlags,
+            mSharedMessage->motion.metaState,
+            mSharedMessage->motion.xOffset,
+            mSharedMessage->motion.yOffset,
+            mSharedMessage->motion.xPrecision,
+            mSharedMessage->motion.yPrecision,
+            mSharedMessage->motion.downTime,
+            mSharedMessage->motion.sampleData[0].eventTime,
+            mSharedMessage->motion.pointerCount,
+            mSharedMessage->motion.pointerIds,
+            mSharedMessage->motion.sampleData[0].coords);
+
+    size_t sampleCount = mSharedMessage->motion.sampleCount;
+    if (sampleCount > 1) {
+        InputMessage::SampleData* sampleData = mSharedMessage->motion.sampleData;
+        size_t sampleDataStride = InputMessage::sampleDataStride(
+                mSharedMessage->motion.pointerCount);
+
+        while (--sampleCount > 0) {
+            sampleData = InputMessage::sampleDataPtrIncrement(sampleData, sampleDataStride);
+            motionEvent->addSample(sampleData->eventTime, sampleData->coords);
+        }
+    }
+}
+
+} // namespace android
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 9b41804..ee186c8 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -59,19 +59,11 @@
     // YUV format from the HAL are handled here
     switch (format) {
     case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-    case HAL_PIXEL_FORMAT_YCrCb_422_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_422_P:
     case HAL_PIXEL_FORMAT_YCbCr_422_I:
-    case HAL_PIXEL_FORMAT_CbYCrY_422_I:
         info->bitsPerPixel = 16;
         goto done;
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP:
     case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-    case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
-    case HAL_PIXEL_FORMAT_YCrCb_420_SP_TILED:
-    case HAL_PIXEL_FORMAT_YCbCr_420_P:
-    case HAL_PIXEL_FORMAT_YCbCr_420_I:
-    case HAL_PIXEL_FORMAT_CbYCrY_420_I:
+    case HAL_PIXEL_FORMAT_YV12:
         info->bitsPerPixel = 12;
      done:
         info->format = format;
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index 66b9576..5694e00 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -18,11 +18,11 @@
 
 namespace android {
 
-static inline int min(int a, int b) {
+static inline int32_t min(int32_t a, int32_t b) {
     return (a<b) ? a : b;
 }
 
-static inline int max(int a, int b) {
+static inline int32_t max(int32_t a, int32_t b) {
     return (a>b) ? a : b;
 }
 
@@ -53,7 +53,7 @@
     return false;
 }
 
-Rect& Rect::offsetTo(int x, int y)
+Rect& Rect::offsetTo(int32_t x, int32_t y)
 {
     right -= left - x;
     bottom -= top - y;
@@ -62,7 +62,7 @@
     return *this;
 }
 
-Rect& Rect::offsetBy(int x, int y)
+Rect& Rect::offsetBy(int32_t x, int32_t y)
 {
     left += x;
     top  += y;
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 6cc4a5a..62f824f 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -1,16 +1,50 @@
+# Build the unit tests.
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-	region.cpp
+ifneq ($(TARGET_SIMULATOR),true)
 
-LOCAL_SHARED_LIBRARIES := \
+# Build the unit tests.
+test_src_files := \
+    InputChannel_test.cpp \
+    InputDispatcher_test.cpp \
+    InputPublisherAndConsumer_test.cpp
+
+shared_libraries := \
 	libcutils \
 	libutils \
-    libui
+	libEGL \
+	libbinder \
+	libpixelflinger \
+	libhardware \
+	libhardware_legacy \
+	libui \
+	libstlport
 
-LOCAL_MODULE:= test-region
+static_libraries := \
+	libgtest \
+	libgtest_main
 
-LOCAL_MODULE_TAGS := tests
+c_includes := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport
 
-include $(BUILD_EXECUTABLE)
+module_tags := eng tests
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
+include $(call all-subdir-makefiles)
+
+endif
\ No newline at end of file
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/ui/tests/InputChannel_test.cpp
new file mode 100644
index 0000000..6cec1c0
--- /dev/null
+++ b/libs/ui/tests/InputChannel_test.cpp
@@ -0,0 +1,158 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputTransport.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <cutils/ashmem.h>
+
+#include "../../utils/tests/TestHelpers.h"
+
+namespace android {
+
+class InputChannelTest : public testing::Test {
+protected:
+    virtual void SetUp() { }
+    virtual void TearDown() { }
+};
+
+
+TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
+    // Our purpose here is to verify that the input channel destructor closes the
+    // file descriptors provided to it.  One easy way is to provide it with one end
+    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
+    Pipe fakeAshmem, sendPipe, receivePipe;
+
+    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"),
+            fakeAshmem.sendFd, receivePipe.receiveFd, sendPipe.sendFd);
+
+    EXPECT_STREQ("channel name", inputChannel->getName().string())
+            << "channel should have provided name";
+    EXPECT_EQ(fakeAshmem.sendFd, inputChannel->getAshmemFd())
+            << "channel should have provided ashmem fd";
+    EXPECT_EQ(receivePipe.receiveFd, inputChannel->getReceivePipeFd())
+            << "channel should have provided receive pipe fd";
+    EXPECT_EQ(sendPipe.sendFd, inputChannel->getSendPipeFd())
+            << "channel should have provided send pipe fd";
+
+    inputChannel.clear(); // destroys input channel
+
+    EXPECT_EQ(-EPIPE, fakeAshmem.readSignal())
+            << "channel should have closed ashmem fd when destroyed";
+    EXPECT_EQ(-EPIPE, receivePipe.writeSignal())
+            << "channel should have closed receive pipe fd when destroyed";
+    EXPECT_EQ(-EPIPE, sendPipe.readSignal())
+            << "channel should have closed send pipe fd when destroyed";
+
+    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
+    fakeAshmem.sendFd = -1;
+    receivePipe.receiveFd = -1;
+    sendPipe.sendFd = -1;
+}
+
+TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    // Name
+    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
+            << "server channel should have suffixed name";
+    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
+            << "client channel should have suffixed name";
+
+    // Ashmem uniqueness
+    EXPECT_NE(serverChannel->getAshmemFd(), clientChannel->getAshmemFd())
+            << "server and client channel should have different ashmem fds because it was dup'd";
+
+    // Ashmem usability
+    ssize_t serverAshmemSize = ashmem_get_size_region(serverChannel->getAshmemFd());
+    ssize_t clientAshmemSize = ashmem_get_size_region(clientChannel->getAshmemFd());
+    uint32_t* serverAshmem = static_cast<uint32_t*>(mmap(NULL, serverAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, serverChannel->getAshmemFd(), 0));
+    uint32_t* clientAshmem = static_cast<uint32_t*>(mmap(NULL, clientAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, clientChannel->getAshmemFd(), 0));
+    ASSERT_TRUE(serverAshmem != NULL)
+            << "server channel ashmem should be mappable";
+    ASSERT_TRUE(clientAshmem != NULL)
+            << "client channel ashmem should be mappable";
+    *serverAshmem = 0xf00dd00d;
+    EXPECT_EQ(0xf00dd00d, *clientAshmem)
+            << "ashmem buffer should be shared by client and server";
+    munmap(serverAshmem, serverAshmemSize);
+    munmap(clientAshmem, clientAshmemSize);
+
+    // Server->Client communication
+    EXPECT_EQ(OK, serverChannel->sendSignal('S'))
+            << "server channel should be able to send signal to client channel";
+    char signal;
+    EXPECT_EQ(OK, clientChannel->receiveSignal(& signal))
+            << "client channel should be able to receive signal from server channel";
+    EXPECT_EQ('S', signal)
+            << "client channel should receive the correct signal from server channel";
+
+    // Client->Server communication
+    EXPECT_EQ(OK, clientChannel->sendSignal('c'))
+            << "client channel should be able to send signal to server channel";
+    EXPECT_EQ(OK, serverChannel->receiveSignal(& signal))
+            << "server channel should be able to receive signal from client channel";
+    EXPECT_EQ('c', signal)
+            << "server channel should receive the correct signal from client channel";
+}
+
+TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    char signal;
+    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveSignal(& signal))
+            << "receiveSignal should have returned WOULD_BLOCK";
+}
+
+TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    serverChannel.clear(); // close server channel
+
+    char signal;
+    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveSignal(& signal))
+            << "receiveSignal should have returned DEAD_OBJECT";
+}
+
+TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    serverChannel.clear(); // close server channel
+
+    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendSignal('S'))
+            << "sendSignal should have returned DEAD_OBJECT";
+}
+
+
+} // namespace android
diff --git a/libs/ui/tests/InputDispatcher_test.cpp b/libs/ui/tests/InputDispatcher_test.cpp
new file mode 100644
index 0000000..1dc6e46
--- /dev/null
+++ b/libs/ui/tests/InputDispatcher_test.cpp
@@ -0,0 +1,18 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputDispatcher.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+class InputDispatcherTest : public testing::Test {
+public:
+};
+
+TEST_F(InputDispatcherTest, Dummy) {
+    // TODO
+}
+
+} // namespace android
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
new file mode 100644
index 0000000..952b974
--- /dev/null
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -0,0 +1,471 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputTransport.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <cutils/ashmem.h>
+
+#include "../../utils/tests/TestHelpers.h"
+
+namespace android {
+
+class InputPublisherAndConsumerTest : public testing::Test {
+protected:
+    sp<InputChannel> serverChannel, clientChannel;
+    InputPublisher* mPublisher;
+    InputConsumer* mConsumer;
+    PreallocatedInputEventFactory mEventFactory;
+
+    virtual void SetUp() {
+        status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+                serverChannel, clientChannel);
+
+        mPublisher = new InputPublisher(serverChannel);
+        mConsumer = new InputConsumer(clientChannel);
+    }
+
+    virtual void TearDown() {
+        if (mPublisher) {
+            delete mPublisher;
+            mPublisher = NULL;
+        }
+
+        if (mConsumer) {
+            delete mConsumer;
+            mConsumer = NULL;
+        }
+
+        serverChannel.clear();
+        clientChannel.clear();
+    }
+
+    void Initialize();
+    void PublishAndConsumeKeyEvent();
+    void PublishAndConsumeMotionEvent(
+            size_t samplesToAppendBeforeDispatch = 0,
+            size_t samplesToAppendAfterDispatch = 0);
+};
+
+TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
+    EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
+    EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
+}
+
+void InputPublisherAndConsumerTest::Initialize() {
+    status_t status;
+
+    status = mPublisher->initialize();
+    ASSERT_EQ(OK, status)
+            << "publisher initialize should return OK";
+
+    status = mConsumer->initialize();
+    ASSERT_EQ(OK, status)
+            << "consumer initialize should return OK";
+}
+
+void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
+    status_t status;
+
+    const int32_t deviceId = 1;
+    const int32_t source = AINPUT_SOURCE_KEYBOARD;
+    const int32_t action = AKEY_EVENT_ACTION_DOWN;
+    const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
+    const int32_t keyCode = AKEYCODE_ENTER;
+    const int32_t scanCode = 13;
+    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+    const int32_t repeatCount = 1;
+    const nsecs_t downTime = 3;
+    const nsecs_t eventTime = 4;
+
+    status = mPublisher->publishKeyEvent(deviceId, source, action, flags,
+            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
+    ASSERT_EQ(OK, status)
+            << "publisher publishKeyEvent should return OK";
+
+    status = mPublisher->sendDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher sendDispatchSignal should return OK";
+
+    status = mConsumer->receiveDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer receiveDispatchSignal should return OK";
+
+    InputEvent* event;
+    status = mConsumer->consume(& mEventFactory, & event);
+    ASSERT_EQ(OK, status)
+            << "consumer consume should return OK";
+
+    ASSERT_TRUE(event != NULL)
+            << "consumer should have returned non-NULL event";
+    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
+            << "consumer should have returned a key event";
+
+    KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
+    EXPECT_EQ(deviceId, keyEvent->getDeviceId());
+    EXPECT_EQ(source, keyEvent->getSource());
+    EXPECT_EQ(action, keyEvent->getAction());
+    EXPECT_EQ(flags, keyEvent->getFlags());
+    EXPECT_EQ(keyCode, keyEvent->getKeyCode());
+    EXPECT_EQ(scanCode, keyEvent->getScanCode());
+    EXPECT_EQ(metaState, keyEvent->getMetaState());
+    EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
+    EXPECT_EQ(downTime, keyEvent->getDownTime());
+    EXPECT_EQ(eventTime, keyEvent->getEventTime());
+
+    status = mConsumer->sendFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer sendFinishedSignal should return OK";
+
+    status = mPublisher->receiveFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher receiveFinishedSignal should return OK";
+
+    status = mPublisher->reset();
+    ASSERT_EQ(OK, status)
+            << "publisher reset should return OK";
+}
+
+void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
+        size_t samplesToAppendBeforeDispatch, size_t samplesToAppendAfterDispatch) {
+    status_t status;
+
+    const int32_t deviceId = 1;
+    const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
+    const int32_t action = AMOTION_EVENT_ACTION_MOVE;
+    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+    const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
+    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+    const float xOffset = -10;
+    const float yOffset = -20;
+    const float xPrecision = 0.25;
+    const float yPrecision = 0.5;
+    const nsecs_t downTime = 3;
+    const size_t pointerCount = 3;
+    const int32_t pointerIds[pointerCount] = { 2, 0, 1 };
+
+    Vector<nsecs_t> sampleEventTimes;
+    Vector<PointerCoords> samplePointerCoords;
+
+    for (size_t i = 0; i <= samplesToAppendAfterDispatch + samplesToAppendBeforeDispatch; i++) {
+        sampleEventTimes.push(i + 10);
+        for (size_t j = 0; j < pointerCount; j++) {
+            samplePointerCoords.push();
+            samplePointerCoords.editTop().x = 100 * i + j;
+            samplePointerCoords.editTop().y = 200 * i + j;
+            samplePointerCoords.editTop().pressure = 0.5 * i + j;
+            samplePointerCoords.editTop().size = 0.7 * i + j;
+            samplePointerCoords.editTop().touchMajor = 1.5 * i + j;
+            samplePointerCoords.editTop().touchMinor = 1.7 * i + j;
+            samplePointerCoords.editTop().toolMajor = 2.5 * i + j;
+            samplePointerCoords.editTop().toolMinor = 2.7 * i + j;
+            samplePointerCoords.editTop().orientation = 3.5 * i + j;
+        }
+    }
+
+    status = mPublisher->publishMotionEvent(deviceId, source, action, flags, edgeFlags,
+            metaState, xOffset, yOffset, xPrecision, yPrecision,
+            downTime, sampleEventTimes[0], pointerCount, pointerIds, samplePointerCoords.array());
+    ASSERT_EQ(OK, status)
+            << "publisher publishMotionEvent should return OK";
+
+    for (size_t i = 0; i < samplesToAppendBeforeDispatch; i++) {
+        size_t sampleIndex = i + 1;
+        status = mPublisher->appendMotionSample(sampleEventTimes[sampleIndex],
+                samplePointerCoords.array() + sampleIndex * pointerCount);
+        ASSERT_EQ(OK, status)
+                << "publisher appendMotionEvent should return OK";
+    }
+
+    status = mPublisher->sendDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher sendDispatchSignal should return OK";
+
+    for (size_t i = 0; i < samplesToAppendAfterDispatch; i++) {
+        size_t sampleIndex = i + 1 + samplesToAppendBeforeDispatch;
+        status = mPublisher->appendMotionSample(sampleEventTimes[sampleIndex],
+                samplePointerCoords.array() + sampleIndex * pointerCount);
+        ASSERT_EQ(OK, status)
+                << "publisher appendMotionEvent should return OK";
+    }
+
+    status = mConsumer->receiveDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer receiveDispatchSignal should return OK";
+
+    InputEvent* event;
+    status = mConsumer->consume(& mEventFactory, & event);
+    ASSERT_EQ(OK, status)
+            << "consumer consume should return OK";
+
+    ASSERT_TRUE(event != NULL)
+            << "consumer should have returned non-NULL event";
+    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
+            << "consumer should have returned a motion event";
+
+    size_t lastSampleIndex = samplesToAppendBeforeDispatch + samplesToAppendAfterDispatch;
+
+    MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
+    EXPECT_EQ(deviceId, motionEvent->getDeviceId());
+    EXPECT_EQ(source, motionEvent->getSource());
+    EXPECT_EQ(action, motionEvent->getAction());
+    EXPECT_EQ(flags, motionEvent->getFlags());
+    EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
+    EXPECT_EQ(metaState, motionEvent->getMetaState());
+    EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
+    EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
+    EXPECT_EQ(downTime, motionEvent->getDownTime());
+    EXPECT_EQ(sampleEventTimes[lastSampleIndex], motionEvent->getEventTime());
+    EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
+    EXPECT_EQ(lastSampleIndex, motionEvent->getHistorySize());
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        SCOPED_TRACE(i);
+        EXPECT_EQ(pointerIds[i], motionEvent->getPointerId(i));
+    }
+
+    for (size_t sampleIndex = 0; sampleIndex < lastSampleIndex; sampleIndex++) {
+        SCOPED_TRACE(sampleIndex);
+        EXPECT_EQ(sampleEventTimes[sampleIndex],
+                motionEvent->getHistoricalEventTime(sampleIndex));
+        for (size_t i = 0; i < pointerCount; i++) {
+            SCOPED_TRACE(i);
+            size_t offset = sampleIndex * pointerCount + i;
+            EXPECT_EQ(samplePointerCoords[offset].x,
+                    motionEvent->getHistoricalRawX(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].y,
+                    motionEvent->getHistoricalRawY(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].x + xOffset,
+                    motionEvent->getHistoricalX(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].y + yOffset,
+                    motionEvent->getHistoricalY(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].pressure,
+                    motionEvent->getHistoricalPressure(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].size,
+                    motionEvent->getHistoricalSize(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].touchMajor,
+                    motionEvent->getHistoricalTouchMajor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].touchMinor,
+                    motionEvent->getHistoricalTouchMinor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].toolMajor,
+                    motionEvent->getHistoricalToolMajor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].toolMinor,
+                    motionEvent->getHistoricalToolMinor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].orientation,
+                    motionEvent->getHistoricalOrientation(i, sampleIndex));
+        }
+    }
+
+    SCOPED_TRACE(lastSampleIndex);
+    EXPECT_EQ(sampleEventTimes[lastSampleIndex], motionEvent->getEventTime());
+    for (size_t i = 0; i < pointerCount; i++) {
+        SCOPED_TRACE(i);
+        size_t offset = lastSampleIndex * pointerCount + i;
+        EXPECT_EQ(samplePointerCoords[offset].x, motionEvent->getRawX(i));
+        EXPECT_EQ(samplePointerCoords[offset].y, motionEvent->getRawY(i));
+        EXPECT_EQ(samplePointerCoords[offset].x + xOffset, motionEvent->getX(i));
+        EXPECT_EQ(samplePointerCoords[offset].y + yOffset, motionEvent->getY(i));
+        EXPECT_EQ(samplePointerCoords[offset].pressure, motionEvent->getPressure(i));
+        EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getSize(i));
+        EXPECT_EQ(samplePointerCoords[offset].touchMajor, motionEvent->getTouchMajor(i));
+        EXPECT_EQ(samplePointerCoords[offset].touchMinor, motionEvent->getTouchMinor(i));
+        EXPECT_EQ(samplePointerCoords[offset].toolMajor, motionEvent->getToolMajor(i));
+        EXPECT_EQ(samplePointerCoords[offset].toolMinor, motionEvent->getToolMinor(i));
+        EXPECT_EQ(samplePointerCoords[offset].orientation, motionEvent->getOrientation(i));
+    }
+
+    status = mConsumer->sendFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer sendFinishedSignal should return OK";
+
+    status = mPublisher->receiveFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher receiveFinishedSignal should return OK";
+
+    status = mPublisher->reset();
+    ASSERT_EQ(OK, status)
+            << "publisher reset should return OK";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_WhenNotReset_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    status = mPublisher->publishKeyEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+    ASSERT_EQ(OK, status)
+            << "publisher publishKeyEvent should return OK first time";
+
+    status = mPublisher->publishKeyEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher publishKeyEvent should return INVALID_OPERATION because "
+                    "the publisher was not reset";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenNotReset_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = 1;
+    int32_t pointerIds[pointerCount] = { 0 };
+    PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status)
+            << "publisher publishMotionEvent should return OK";
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher publishMotionEvent should return INVALID_OPERATION because ";
+                    "the publisher was not reset";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = 0;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(BAD_VALUE, status)
+            << "publisher publishMotionEvent should return BAD_VALUE";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS + 1;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(BAD_VALUE, status)
+            << "publisher publishMotionEvent should return BAD_VALUE";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenCalledBeforeDispatchSignal_AppendsSamples) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent(3, 0));
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenCalledAfterDispatchSignalAndNotConsumed_AppendsSamples) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent(0, 4));
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenNoMotionEventPublished_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    PointerCoords pointerCoords[1];
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher appendMotionSample should return INVALID_OPERATION";
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenPublishedMotionEventIsNotAMove_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_DOWN,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status);
+
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher appendMotionSample should return INVALID_OPERATION";
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenAlreadyConsumed_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status);
+
+    status = mPublisher->sendDispatchSignal();
+    ASSERT_EQ(OK, status);
+
+    status = mConsumer->receiveDispatchSignal();
+    ASSERT_EQ(OK, status);
+
+    InputEvent* event;
+    status = mConsumer->consume(& mEventFactory, & event);
+    ASSERT_EQ(OK, status);
+
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(status_t(FAILED_TRANSACTION), status)
+            << "publisher appendMotionSample should return FAILED_TRANSACTION";
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenBufferFull_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status);
+
+    for (int count = 1;; count++) {
+        ASSERT_LT(count, 100000) << "should eventually reach OOM";
+
+        status = mPublisher->appendMotionSample(0, pointerCoords);
+        if (status != OK) {
+            ASSERT_GT(count, 12) << "should be able to add at least a dozen samples";
+            ASSERT_EQ(NO_MEMORY, status)
+                    << "publisher appendMotionSample should return NO_MEMORY when buffer is full";
+            break;
+        }
+    }
+
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(NO_MEMORY, status)
+            << "publisher appendMotionSample should return NO_MEMORY persistently until reset";
+}
+
+} // namespace android
diff --git a/libs/ui/tests/region/Android.mk b/libs/ui/tests/region/Android.mk
new file mode 100644
index 0000000..6cc4a5a
--- /dev/null
+++ b/libs/ui/tests/region/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	region.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-region
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/ui/tests/region.cpp b/libs/ui/tests/region/region.cpp
similarity index 100%
rename from libs/ui/tests/region.cpp
rename to libs/ui/tests/region/region.cpp
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index afecdcb..2e20268 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -26,11 +26,14 @@
 	Debug.cpp \
 	FileMap.cpp \
 	Flattenable.cpp \
+	ObbFile.cpp \
+	Pool.cpp \
 	RefBase.cpp \
 	ResourceTypes.cpp \
 	SharedBuffer.cpp \
 	Static.cpp \
 	StopWatch.cpp \
+	StreamingZipInflater.cpp \
 	String8.cpp \
 	String16.cpp \
 	StringArray.cpp \
@@ -39,7 +42,7 @@
 	Threads.cpp \
 	Timers.cpp \
 	VectorImpl.cpp \
-    ZipFileCRO.cpp \
+	ZipFileCRO.cpp \
 	ZipFileRO.cpp \
 	ZipUtils.cpp \
 	misc.cpp
@@ -64,6 +67,11 @@
 endif
 endif
 
+ifeq ($(HOST_OS),darwin)
+# MacOS doesn't have lseek64. However, off_t is 64-bit anyway.
+LOCAL_CFLAGS += -DOFF_T_IS_64_BIT
+endif
+
 include $(BUILD_HOST_STATIC_LIBRARY)
 
 
@@ -76,8 +84,9 @@
 # we have the common sources, plus some device-specific stuff
 LOCAL_SRC_FILES:= \
 	$(commonSources) \
-    BackupData.cpp \
-	BackupHelpers.cpp
+	BackupData.cpp \
+	BackupHelpers.cpp \
+	PollLoop.cpp
 
 ifeq ($(TARGET_OS),linux)
 LOCAL_LDLIBS += -lrt -ldl
@@ -114,3 +123,13 @@
 include $(BUILD_STATIC_LIBRARY)
 endif
 endif
+
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
index 4295123..cef7db4 100644
--- a/libs/utils/Asset.cpp
+++ b/libs/utils/Asset.cpp
@@ -24,6 +24,7 @@
 #include <utils/Asset.h>
 #include <utils/Atomic.h>
 #include <utils/FileMap.h>
+#include <utils/StreamingZipInflater.h>
 #include <utils/ZipUtils.h>
 #include <utils/ZipFileRO.h>
 #include <utils/Log.h>
@@ -659,7 +660,7 @@
  */
 _CompressedAsset::_CompressedAsset(void)
     : mStart(0), mCompressedLen(0), mUncompressedLen(0), mOffset(0),
-      mMap(NULL), mFd(-1), mBuf(NULL)
+      mMap(NULL), mFd(-1), mZipInflater(NULL), mBuf(NULL)
 {
 }
 
@@ -698,6 +699,10 @@
     mFd = fd;
     assert(mBuf == NULL);
 
+    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
+        mZipInflater = new StreamingZipInflater(mFd, offset, uncompressedLen, compressedLen);
+    }
+
     return NO_ERROR;
 }
 
@@ -724,6 +729,9 @@
     mUncompressedLen = uncompressedLen;
     assert(mOffset == 0);
 
+    if (uncompressedLen > StreamingZipInflater::OUTPUT_CHUNK_SIZE) {
+        mZipInflater = new StreamingZipInflater(dataMap, uncompressedLen);
+    }
     return NO_ERROR;
 }
 
@@ -739,26 +747,29 @@
 
     assert(mOffset >= 0 && mOffset <= mUncompressedLen);
 
-    // TODO: if mAccessMode == ACCESS_STREAMING, use zlib more cleverly
+    /* If we're relying on a streaming inflater, go through that */
+    if (mZipInflater) {
+        actual = mZipInflater->read(buf, count);
+    } else {
+        if (mBuf == NULL) {
+            if (getBuffer(false) == NULL)
+                return -1;
+        }
+        assert(mBuf != NULL);
 
-    if (mBuf == NULL) {
-        if (getBuffer(false) == NULL)
-            return -1;
+        /* adjust count if we're near EOF */
+        maxLen = mUncompressedLen - mOffset;
+        if (count > maxLen)
+            count = maxLen;
+
+        if (!count)
+            return 0;
+
+        /* copy from buffer */
+        //printf("comp buf read\n");
+        memcpy(buf, (char*)mBuf + mOffset, count);
+        actual = count;
     }
-    assert(mBuf != NULL);
-
-    /* adjust count if we're near EOF */
-    maxLen = mUncompressedLen - mOffset;
-    if (count > maxLen)
-        count = maxLen;
-
-    if (!count)
-        return 0;
-
-    /* copy from buffer */
-    //printf("comp buf read\n");
-    memcpy(buf, (char*)mBuf + mOffset, count);
-    actual = count;
 
     mOffset += actual;
     return actual;
@@ -780,6 +791,9 @@
     if (newPosn == (off_t) -1)
         return newPosn;
 
+    if (mZipInflater) {
+        mZipInflater->seekAbsolute(newPosn);
+    }
     mOffset = newPosn;
     return mOffset;
 }
@@ -793,10 +807,12 @@
         mMap->release();
         mMap = NULL;
     }
-    if (mBuf != NULL) {
-        delete[] mBuf;
-        mBuf = NULL;
-    }
+
+    delete[] mBuf;
+    mBuf = NULL;
+
+    delete mZipInflater;
+    mZipInflater = NULL;
 
     if (mFd > 0) {
         ::close(mFd);
@@ -817,12 +833,6 @@
     if (mBuf != NULL)
         return mBuf;
 
-    if (mUncompressedLen > UNCOMPRESS_DATA_MAX) {
-        LOGD("Data exceeds UNCOMPRESS_DATA_MAX (%ld vs %d)\n",
-            (long) mUncompressedLen, UNCOMPRESS_DATA_MAX);
-        goto bail;
-    }
-
     /*
      * Allocate a buffer and read the file into it.
      */
@@ -853,7 +863,13 @@
             goto bail;
     }
 
-    /* success! */
+    /*
+     * Success - now that we have the full asset in RAM we
+     * no longer need the streaming inflater
+     */
+    delete mZipInflater;
+    mZipInflater = NULL;
+
     mBuf = buf;
     buf = NULL;
 
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
index 5a05e6a..e09e755 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/utils/AssetManager.cpp
@@ -232,6 +232,12 @@
     }
 }
 
+void AssetManager::getConfiguration(ResTable_config* outConfig) const
+{
+    AutoMutex _l(mLock);
+    *outConfig = *mConfig;
+}
+
 /*
  * Open an asset.
  *
@@ -824,7 +830,7 @@
 
     // TODO: look for previously-created shared memory slice?
     int method;
-    long uncompressedLen;
+    size_t uncompressedLen;
 
     //printf("USING Zip '%s'\n", pEntry->getFileName());
 
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
new file mode 100644
index 0000000..e170ab8
--- /dev/null
+++ b/libs/utils/ObbFile.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LOG_TAG "ObbFile"
+#include <utils/Log.h>
+#include <utils/ObbFile.h>
+
+//#define DEBUG 1
+
+#define kFooterTagSize 8  /* last two 32-bit integers */
+
+#define kFooterMinSize 25 /* 32-bit signature version (4 bytes)
+                           * 32-bit package version (4 bytes)
+                           * 32-bit flags (4 bytes)
+                           * 32-bit package name size (4-bytes)
+                           * >=1-character package name (1 byte)
+                           * 32-bit footer size (4 bytes)
+                           * 32-bit footer marker (4 bytes)
+                           */
+
+#define kMaxBufSize    32768 /* Maximum file read buffer */
+
+#define kSignature     0x01059983U /* ObbFile signature */
+
+#define kSigVersion    1 /* We only know about signature version 1 */
+
+/* offsets in version 1 of the header */
+#define kPackageVersionOffset 4
+#define kFlagsOffset          8
+#define kPackageNameLenOffset 12
+#define kPackageNameOffset    16
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+/*
+ * Work around situations where off_t is 64-bit and use off64_t in
+ * situations where it's 32-bit.
+ */
+#ifdef OFF_T_IS_64_BIT
+#define my_lseek64 lseek
+typedef off_t my_off64_t;
+#else
+#define my_lseek64 lseek64
+typedef off64_t my_off64_t;
+#endif
+
+namespace android {
+
+ObbFile::ObbFile() :
+        mPackageName(""),
+        mVersion(-1),
+        mFlags(0)
+{
+}
+
+ObbFile::~ObbFile() {
+}
+
+bool ObbFile::readFrom(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_RDONLY);
+    if (fd < 0) {
+        LOGW("couldn't open file %s: %s", filename, strerror(errno));
+        goto out;
+    }
+    success = readFrom(fd);
+    close(fd);
+
+    if (!success) {
+        LOGW("failed to read from %s (fd=%d)\n", filename, fd);
+    }
+
+out:
+    return success;
+}
+
+bool ObbFile::readFrom(int fd)
+{
+    if (fd < 0) {
+        LOGW("attempt to read from invalid fd\n");
+        return false;
+    }
+
+    return parseObbFile(fd);
+}
+
+bool ObbFile::parseObbFile(int fd)
+{
+    my_off64_t fileLength = my_lseek64(fd, 0, SEEK_END);
+
+    if (fileLength < kFooterMinSize) {
+        if (fileLength < 0) {
+            LOGW("error seeking in ObbFile: %s\n", strerror(errno));
+        } else {
+            LOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
+        }
+        return false;
+    }
+
+    ssize_t actual;
+    size_t footerSize;
+
+    {
+        my_lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
+
+        char *footer = new char[kFooterTagSize];
+        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
+        if (actual != kFooterTagSize) {
+            LOGW("couldn't read footer signature: %s\n", strerror(errno));
+            return false;
+        }
+
+        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
+        if (fileSig != kSignature) {
+            LOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
+                    kSignature, fileSig);
+            return false;
+        }
+
+        footerSize = get4LE((unsigned char*)footer);
+        if (footerSize > (size_t)fileLength - kFooterTagSize
+                || footerSize > kMaxBufSize) {
+            LOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
+                    footerSize, fileLength);
+            return false;
+        }
+
+        if (footerSize < (kFooterMinSize - kFooterTagSize)) {
+            LOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
+                    footerSize, kFooterMinSize - kFooterTagSize);
+            return false;
+        }
+    }
+
+    my_off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
+    if (my_lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
+        LOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
+        return false;
+    }
+
+    mFooterStart = fileOffset;
+
+    char* scanBuf = (char*)malloc(footerSize);
+    if (scanBuf == NULL) {
+        LOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
+        return false;
+    }
+
+    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
+    // readAmount is guaranteed to be less than kMaxBufSize
+    if (actual != (ssize_t)footerSize) {
+        LOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+#ifdef DEBUG
+    for (int i = 0; i < footerSize; ++i) {
+        LOGI("char: 0x%02x", scanBuf[i]);
+    }
+#endif
+
+    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
+    if (sigVersion != kSigVersion) {
+        LOGW("Unsupported ObbFile version %d\n", sigVersion);
+        free(scanBuf);
+        return false;
+    }
+
+    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
+    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
+
+    uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
+    if (packageNameLen <= 0
+            || packageNameLen > (footerSize - kPackageNameOffset)) {
+        LOGW("bad ObbFile package name length (0x%04x; 0x%04x possible)\n",
+                packageNameLen, footerSize - kPackageNameOffset);
+        free(scanBuf);
+        return false;
+    }
+
+    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
+    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
+
+    free(scanBuf);
+
+#ifdef DEBUG
+    LOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
+#endif
+
+    return true;
+}
+
+bool ObbFile::writeTo(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_WRONLY);
+    if (fd < 0) {
+        goto out;
+    }
+    success = writeTo(fd);
+    close(fd);
+
+out:
+    if (!success) {
+        LOGW("failed to write to %s: %s\n", filename, strerror(errno));
+    }
+    return success;
+}
+
+bool ObbFile::writeTo(int fd)
+{
+    if (fd < 0) {
+        return false;
+    }
+
+    my_lseek64(fd, 0, SEEK_END);
+
+    if (mPackageName.size() == 0 || mVersion == -1) {
+        LOGW("tried to write uninitialized ObbFile data");
+        return false;
+    }
+
+    unsigned char intBuf[sizeof(uint32_t)+1];
+    memset(&intBuf, 0, sizeof(intBuf));
+
+    put4LE(intBuf, kSigVersion);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write signature version: %s", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, mVersion);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package version");
+        return false;
+    }
+
+    put4LE(intBuf, mFlags);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package version");
+        return false;
+    }
+
+    size_t packageNameLen = mPackageName.size();
+    put4LE(intBuf, packageNameLen);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package name length: %s", strerror(errno));
+        return false;
+    }
+
+    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
+        LOGW("couldn't write package name: %s", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, kPackageNameOffset + packageNameLen);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write footer size: %s", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, kSignature);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write footer magic signature: %s", strerror(errno));
+        return false;
+    }
+
+    return true;
+}
+
+bool ObbFile::removeFrom(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_RDWR);
+    if (fd < 0) {
+        goto out;
+    }
+    success = removeFrom(fd);
+    close(fd);
+
+out:
+    if (!success) {
+        LOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
+    }
+    return success;
+}
+
+bool ObbFile::removeFrom(int fd)
+{
+    if (fd < 0) {
+        return false;
+    }
+
+    if (!readFrom(fd)) {
+        return false;
+    }
+
+    ftruncate(fd, mFooterStart);
+
+    return true;
+}
+
+}
diff --git a/libs/utils/PollLoop.cpp b/libs/utils/PollLoop.cpp
new file mode 100644
index 0000000..6d3eeee
--- /dev/null
+++ b/libs/utils/PollLoop.cpp
@@ -0,0 +1,371 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// A select loop implementation.
+//
+#define LOG_TAG "PollLoop"
+
+//#define LOG_NDEBUG 0
+
+// Debugs poll and wake interactions.
+#define DEBUG_POLL_AND_WAKE 0
+
+// Debugs callback registration and invocation.
+#define DEBUG_CALLBACKS 0
+
+#include <cutils/log.h>
+#include <utils/PollLoop.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+namespace android {
+
+static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
+static bool gHaveTLS = false;
+static pthread_key_t gTLS = 0;
+
+PollLoop::PollLoop(bool allowNonCallbacks) :
+        mAllowNonCallbacks(allowNonCallbacks), mPolling(false),
+        mWaiters(0), mPendingFdsPos(0) {
+    openWakePipe();
+}
+
+PollLoop::~PollLoop() {
+    closeWakePipe();
+}
+
+void PollLoop::threadDestructor(void *st) {
+    PollLoop* const self = static_cast<PollLoop*>(st);
+    if (self != NULL) {
+        self->decStrong((void*)threadDestructor);
+    }
+}
+
+void PollLoop::setForThread(const sp<PollLoop>& pollLoop) {
+    sp<PollLoop> old = getForThread();
+    
+    if (pollLoop != NULL) {
+        pollLoop->incStrong((void*)threadDestructor);
+    }
+    
+    pthread_setspecific(gTLS, pollLoop.get());
+    
+    if (old != NULL) {
+        old->decStrong((void*)threadDestructor);
+    }
+}
+    
+sp<PollLoop> PollLoop::getForThread() {
+    if (!gHaveTLS) {
+        pthread_mutex_lock(&gTLSMutex);
+        if (pthread_key_create(&gTLS, threadDestructor) != 0) {
+            pthread_mutex_unlock(&gTLSMutex);
+            return NULL;
+        }
+        gHaveTLS = true;
+        pthread_mutex_unlock(&gTLSMutex);
+    }
+    
+    return (PollLoop*)pthread_getspecific(gTLS);
+}
+
+void PollLoop::openWakePipe() {
+    int wakeFds[2];
+    int result = pipe(wakeFds);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe.  errno=%d", errno);
+
+    mWakeReadPipeFd = wakeFds[0];
+    mWakeWritePipeFd = wakeFds[1];
+
+    result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking.  errno=%d",
+            errno);
+
+    result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking.  errno=%d",
+            errno);
+
+    // Add the wake pipe to the head of the request list with a null callback.
+    struct pollfd requestedFd;
+    requestedFd.fd = mWakeReadPipeFd;
+    requestedFd.events = POLLIN;
+    mRequestedFds.insertAt(requestedFd, 0);
+
+    RequestedCallback requestedCallback;
+    requestedCallback.callback = NULL;
+    requestedCallback.looperCallback = NULL;
+    requestedCallback.ident = 0;
+    requestedCallback.data = NULL;
+    mRequestedCallbacks.insertAt(requestedCallback, 0);
+}
+
+void PollLoop::closeWakePipe() {
+    close(mWakeReadPipeFd);
+    close(mWakeWritePipeFd);
+
+    // Note: We don't need to remove the poll structure or callback entry because this
+    //       method is currently only called by the destructor.
+}
+
+int32_t PollLoop::pollOnce(int timeoutMillis, int* outEvents, void** outData) {
+    // If there are still pending fds from the last call, dispatch those
+    // first, to avoid an earlier fd from starving later ones.
+    const size_t pendingFdsCount = mPendingFds.size();
+    if (mPendingFdsPos < pendingFdsCount) {
+        const PendingCallback& pending = mPendingFds.itemAt(mPendingFdsPos);
+        mPendingFdsPos++;
+        if (outEvents != NULL) *outEvents = pending.events;
+        if (outData != NULL) *outData = pending.data;
+        return pending.ident;
+    }
+    
+    mLock.lock();
+    while (mWaiters != 0) {
+        mResume.wait(mLock);
+    }
+    mPolling = true;
+    mLock.unlock();
+
+    int32_t result;
+    size_t requestedCount = mRequestedFds.size();
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - waiting on %d fds", this, requestedCount);
+    for (size_t i = 0; i < requestedCount; i++) {
+        LOGD("  fd %d - events %d", mRequestedFds[i].fd, mRequestedFds[i].events);
+    }
+#endif
+
+    int respondedCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis);
+
+    if (respondedCount == 0) {
+        // Timeout
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - timeout", this);
+#endif
+        result = POLL_TIMEOUT;
+        goto Done;
+    }
+
+    if (respondedCount < 0) {
+        // Error
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - error, errno=%d", this, errno);
+#endif
+        if (errno != EINTR) {
+            LOGW("Poll failed with an unexpected error, errno=%d", errno);
+        }
+        result = POLL_ERROR;
+        goto Done;
+    }
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - handling responses from %d fds", this, respondedCount);
+    for (size_t i = 0; i < requestedCount; i++) {
+        LOGD("  fd %d - events %d, revents %d", mRequestedFds[i].fd, mRequestedFds[i].events,
+                mRequestedFds[i].revents);
+    }
+#endif
+
+    mPendingCallbacks.clear();
+    mPendingFds.clear();
+    mPendingFdsPos = 0;
+    if (outEvents != NULL) *outEvents = 0;
+    if (outData != NULL) *outData = NULL;
+    
+    result = POLL_CALLBACK;
+    for (size_t i = 0; i < requestedCount; i++) {
+        const struct pollfd& requestedFd = mRequestedFds.itemAt(i);
+
+        short revents = requestedFd.revents;
+        if (revents) {
+            const RequestedCallback& requestedCallback = mRequestedCallbacks.itemAt(i);
+            PendingCallback pending;
+            pending.fd = requestedFd.fd;
+            pending.ident = requestedCallback.ident;
+            pending.events = revents;
+            pending.callback = requestedCallback.callback;
+            pending.looperCallback = requestedCallback.looperCallback;
+            pending.data = requestedCallback.data;
+
+            if (pending.callback || pending.looperCallback) {
+                mPendingCallbacks.push(pending);
+            } else if (pending.fd != mWakeReadPipeFd) {
+                if (result == POLL_CALLBACK) {
+                    result = pending.ident;
+                    if (outEvents != NULL) *outEvents = pending.events;
+                    if (outData != NULL) *outData = pending.data;
+                } else {
+                    mPendingFds.push(pending);
+                }
+            } else {
+#if DEBUG_POLL_AND_WAKE
+                LOGD("%p ~ pollOnce - awoken", this);
+#endif
+                char buffer[16];
+                ssize_t nRead;
+                do {
+                    nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
+                } while (nRead == sizeof(buffer));
+            }
+
+            respondedCount -= 1;
+            if (respondedCount == 0) {
+                break;
+            }
+        }
+    }
+
+Done:
+    mLock.lock();
+    mPolling = false;
+    if (mWaiters != 0) {
+        mAwake.broadcast();
+    }
+    mLock.unlock();
+
+    if (result == POLL_CALLBACK || result >= 0) {
+        size_t pendingCount = mPendingCallbacks.size();
+        for (size_t i = 0; i < pendingCount; i++) {
+            const PendingCallback& pendingCallback = mPendingCallbacks.itemAt(i);
+#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
+            LOGD("%p ~ pollOnce - invoking callback for fd %d", this, pendingCallback.fd);
+#endif
+
+            bool keep = true;
+            if (pendingCallback.callback != NULL) {
+                keep = pendingCallback.callback(pendingCallback.fd, pendingCallback.events,
+                        pendingCallback.data);
+            } else {
+                keep = pendingCallback.looperCallback(pendingCallback.fd, pendingCallback.events,
+                        pendingCallback.data) != 0;
+            }
+            if (! keep) {
+                removeCallback(pendingCallback.fd);
+            }
+        }
+    }
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - done", this);
+#endif
+    return result;
+}
+
+void PollLoop::wake() {
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ wake", this);
+#endif
+
+    ssize_t nWrite = write(mWakeWritePipeFd, "W", 1);
+    if (nWrite != 1) {
+        if (errno != EAGAIN) {
+            LOGW("Could not write wake signal, errno=%d", errno);
+        }
+    }
+}
+
+bool PollLoop::getAllowNonCallbacks() const {
+    return mAllowNonCallbacks;
+}
+
+void PollLoop::setCallback(int fd, int ident, int events, Callback callback, void* data) {
+    setCallbackCommon(fd, ident, events, callback, NULL, data);
+}
+
+void PollLoop::setCallback(int fd, int events, Callback callback, void* data) {
+    setCallbackCommon(fd, POLL_CALLBACK, events, callback, NULL, data);
+}
+
+void PollLoop::setLooperCallback(int fd, int ident, int events, ALooper_callbackFunc* callback,
+        void* data) {
+    setCallbackCommon(fd, ident, events, NULL, callback, data);
+}
+
+void PollLoop::setCallbackCommon(int fd, int ident, int events, Callback callback,
+        ALooper_callbackFunc* looperCallback, void* data) {
+
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ setCallback - fd=%d, events=%d", this, fd, events);
+#endif
+
+    if (! events) {
+        LOGE("Invalid attempt to set a callback with no selected poll events.");
+        removeCallback(fd);
+        return;
+    }
+
+    if (! callback && ! looperCallback && ! mAllowNonCallbacks) {
+        LOGE("Invalid attempt to set NULL callback but not allowed.");
+        removeCallback(fd);
+        return;
+    }
+    
+    wakeAndLock();
+
+    struct pollfd requestedFd;
+    requestedFd.fd = fd;
+    requestedFd.events = events;
+
+    RequestedCallback requestedCallback;
+    requestedCallback.callback = callback;
+    requestedCallback.looperCallback = looperCallback;
+    requestedCallback.ident = ident;
+    requestedCallback.data = data;
+
+    ssize_t index = getRequestIndexLocked(fd);
+    if (index < 0) {
+        mRequestedFds.push(requestedFd);
+        mRequestedCallbacks.push(requestedCallback);
+    } else {
+        mRequestedFds.replaceAt(requestedFd, size_t(index));
+        mRequestedCallbacks.replaceAt(requestedCallback, size_t(index));
+    }
+
+    mLock.unlock();
+}
+
+bool PollLoop::removeCallback(int fd) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ removeCallback - fd=%d", this, fd);
+#endif
+
+    wakeAndLock();
+
+    ssize_t index = getRequestIndexLocked(fd);
+    if (index >= 0) {
+        mRequestedFds.removeAt(size_t(index));
+        mRequestedCallbacks.removeAt(size_t(index));
+    }
+
+    mLock.unlock();
+    return index >= 0;
+}
+
+ssize_t PollLoop::getRequestIndexLocked(int fd) {
+    size_t requestCount = mRequestedFds.size();
+
+    for (size_t i = 0; i < requestCount; i++) {
+        if (mRequestedFds.itemAt(i).fd == fd) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+void PollLoop::wakeAndLock() {
+    mLock.lock();
+    mWaiters += 1;
+    while (mPolling) {
+        wake();
+        mAwake.wait(mLock);
+    }
+    mWaiters -= 1;
+    if (mWaiters == 0) {
+        mResume.signal();
+    }
+}
+
+} // namespace android
diff --git a/libs/utils/Pool.cpp b/libs/utils/Pool.cpp
new file mode 100644
index 0000000..8f18cb9
--- /dev/null
+++ b/libs/utils/Pool.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// A simple memory pool.
+//
+#define LOG_TAG "Pool"
+
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <utils/Pool.h>
+
+#include <stdlib.h>
+
+namespace android {
+
+// TODO Provide a real implementation of a pool.  This is just a stub for initial development.
+
+PoolImpl::PoolImpl(size_t objSize) :
+    mObjSize(objSize) {
+}
+
+PoolImpl::~PoolImpl() {
+}
+
+void* PoolImpl::allocImpl() {
+    void* ptr = malloc(mObjSize);
+    LOG_ALWAYS_FATAL_IF(ptr == NULL, "Cannot allocate new pool object.");
+    return ptr;
+}
+
+void PoolImpl::freeImpl(void* obj) {
+    LOG_ALWAYS_FATAL_IF(obj == NULL, "Caller attempted to free NULL pool object.");
+    return free(obj);
+}
+
+} // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7e0f881..8345cc3 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1934,8 +1934,8 @@
         ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
         if (offset <= 0) {
             if (offset < 0) {
-                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %d: 0x%08x\n",
-                        resID, t, e, (int)ip, (int)offset);
+                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
+                        resID, t, e, ip, (int)offset);
                 return offset;
             }
             continue;
@@ -4178,6 +4178,9 @@
                             case ResTable_config::SCREENSIZE_LARGE:
                                 printf(" (large)");
                                 break;
+                            case ResTable_config::SCREENSIZE_XLARGE:
+                                printf(" (xlarge)");
+                                break;
                         }
                         printf(" lng=%d",
                                 type->config.screenLayout&ResTable_config::MASK_SCREENLONG);
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
index 68a1c52..b5dda2f 100644
--- a/libs/utils/StopWatch.cpp
+++ b/libs/utils/StopWatch.cpp
@@ -30,10 +30,9 @@
 
 
 StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
-    :   mName(name), mClock(clock), mFlags(flags),
-        mStartTime(0), mNumLaps(0)
+    :   mName(name), mClock(clock), mFlags(flags)
 {
-    mStartTime = systemTime(mClock);
+    reset();
 }
 
 StopWatch::~StopWatch()
@@ -72,6 +71,12 @@
     return systemTime(mClock) - mStartTime;
 }
 
+void StopWatch::reset()
+{
+    mNumLaps = 0;
+    mStartTime = systemTime(mClock);
+}
+
 
 /*****************************************************************************/
 
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/utils/StreamingZipInflater.cpp
new file mode 100644
index 0000000..7ebde78
--- /dev/null
+++ b/libs/utils/StreamingZipInflater.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "szipinf"
+#include <utils/Log.h>
+
+#include <utils/FileMap.h>
+#include <utils/StreamingZipInflater.h>
+#include <string.h>
+#include <stddef.h>
+#include <assert.h>
+
+static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
+
+using namespace android;
+
+/*
+ * Streaming access to compressed asset data in an open fd
+ */
+StreamingZipInflater::StreamingZipInflater(int fd, off_t compDataStart,
+        size_t uncompSize, size_t compSize) {
+    mFd = fd;
+    mDataMap = NULL;
+    mInFileStart = compDataStart;
+    mOutTotalSize = uncompSize;
+    mInTotalSize = compSize;
+
+    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;
+    mInBuf = new uint8_t[mInBufSize];
+
+    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
+    mOutBuf = new uint8_t[mOutBufSize];
+
+    initInflateState();
+}
+
+/*
+ * Streaming access to compressed data held in an mmapped region of memory
+ */
+StreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {
+    mFd = -1;
+    mDataMap = dataMap;
+    mOutTotalSize = uncompSize;
+    mInTotalSize = dataMap->getDataLength();
+
+    mInBuf = (uint8_t*) dataMap->getDataPtr();
+    mInBufSize = mInTotalSize;
+
+    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
+    mOutBuf = new uint8_t[mOutBufSize];
+
+    initInflateState();
+}
+
+StreamingZipInflater::~StreamingZipInflater() {
+    // tear down the in-flight zip state just in case
+    ::inflateEnd(&mInflateState);
+
+    if (mDataMap == NULL) {
+        delete [] mInBuf;
+    }
+    delete [] mOutBuf;
+}
+
+void StreamingZipInflater::initInflateState() {
+    LOGD("Initializing inflate state");
+
+    memset(&mInflateState, 0, sizeof(mInflateState));
+    mInflateState.zalloc = Z_NULL;
+    mInflateState.zfree = Z_NULL;
+    mInflateState.opaque = Z_NULL;
+    mInflateState.next_in = (Bytef*)mInBuf;
+    mInflateState.next_out = (Bytef*) mOutBuf;
+    mInflateState.avail_out = mOutBufSize;
+    mInflateState.data_type = Z_UNKNOWN;
+
+    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;
+    mInNextChunkOffset = 0;
+    mStreamNeedsInit = true;
+
+    if (mDataMap == NULL) {
+        ::lseek(mFd, mInFileStart, SEEK_SET);
+        mInflateState.avail_in = 0; // set when a chunk is read in
+    } else {
+        mInflateState.avail_in = mInBufSize;
+    }
+}
+
+/*
+ * Basic approach:
+ *
+ * 1. If we have undelivered uncompressed data, send it.  At this point
+ *    either we've satisfied the request, or we've exhausted the available
+ *    output data in mOutBuf.
+ *
+ * 2. While we haven't sent enough data to satisfy the request:
+ *    0. if the request is for more data than exists, bail.
+ *    a. if there is no input data to decode, read some into the input buffer
+ *       and readjust the z_stream input pointers
+ *    b. point the output to the start of the output buffer and decode what we can
+ *    c. deliver whatever output data we can
+ */
+ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
+    uint8_t* dest = (uint8_t*) outBuf;
+    size_t bytesRead = 0;
+    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));
+    while (toRead > 0) {
+        // First, write from whatever we already have decoded and ready to go
+        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);
+        if (deliverable > 0) {
+            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);
+            mOutDeliverable += deliverable;
+            mOutCurPosition += deliverable;
+            dest += deliverable;
+            bytesRead += deliverable;
+            toRead -= deliverable;
+        }
+
+        // need more data?  time to decode some.
+        if (toRead > 0) {
+            // if we don't have any data to decode, read some in.  If we're working
+            // from mmapped data this won't happen, because the clipping to total size
+            // will prevent reading off the end of the mapped input chunk.
+            if (mInflateState.avail_in == 0) {
+                int err = readNextChunk();
+                if (err < 0) {
+                    LOGE("Unable to access asset data: %d", err);
+                    if (!mStreamNeedsInit) {
+                        ::inflateEnd(&mInflateState);
+                        initInflateState();
+                    }
+                    return -1;
+                }
+            }
+            // we know we've drained whatever is in the out buffer now, so just
+            // start from scratch there, reading all the input we have at present.
+            mInflateState.next_out = (Bytef*) mOutBuf;
+            mInflateState.avail_out = mOutBufSize;
+
+            /*
+            LOGD("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
+                    mInflateState.avail_in, mInflateState.avail_out,
+                    mInflateState.next_in, mInflateState.next_out);
+            */
+            int result = Z_OK;
+            if (mStreamNeedsInit) {
+                LOGI("Initializing zlib to inflate");
+                result = inflateInit2(&mInflateState, -MAX_WBITS);
+                mStreamNeedsInit = false;
+            }
+            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);
+            if (result < 0) {
+                // Whoops, inflation failed
+                LOGE("Error inflating asset: %d", result);
+                ::inflateEnd(&mInflateState);
+                initInflateState();
+                return -1;
+            } else {
+                if (result == Z_STREAM_END) {
+                    // we know we have to have reached the target size here and will
+                    // not try to read any further, so just wind things up.
+                    ::inflateEnd(&mInflateState);
+                }
+
+                // Note how much data we got, and off we go
+                mOutDeliverable = 0;
+                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;
+            }
+        }
+    }
+    return bytesRead;
+}
+
+int StreamingZipInflater::readNextChunk() {
+    assert(mDataMap == NULL);
+
+    if (mInNextChunkOffset < mInTotalSize) {
+        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
+        if (toRead > 0) {
+            ssize_t didRead = ::read(mFd, mInBuf, toRead);
+            //LOGD("Reading input chunk, size %08x didread %08x", toRead, didRead);
+            if (didRead < 0) {
+                // TODO: error
+                LOGE("Error reading asset data");
+                return didRead;
+            } else {
+                mInNextChunkOffset += didRead;
+                mInflateState.next_in = (Bytef*) mInBuf;
+                mInflateState.avail_in = didRead;
+            }
+        }
+    }
+    return 0;
+}
+
+// seeking backwards requires uncompressing fom the beginning, so is very
+// expensive.  seeking forwards only requires uncompressing from the current
+// position to the destination.
+off_t StreamingZipInflater::seekAbsolute(off_t absoluteInputPosition) {
+    if (absoluteInputPosition < mOutCurPosition) {
+        // rewind and reprocess the data from the beginning
+        if (!mStreamNeedsInit) {
+            ::inflateEnd(&mInflateState);
+        }
+        initInflateState();
+        read(NULL, absoluteInputPosition);
+    } else if (absoluteInputPosition > mOutCurPosition) {
+        read(NULL, absoluteInputPosition - mOutCurPosition);
+    }
+    // else if the target position *is* our current position, do nothing
+    return absoluteInputPosition;
+}
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index 636cd83..1c4f80c 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -301,8 +301,9 @@
 
 status_t String8::setTo(const char* other)
 {
+    const char *newString = allocFromUTF8(other, strlen(other));
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF8(other, strlen(other));
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -311,8 +312,9 @@
 
 status_t String8::setTo(const char* other, size_t len)
 {
+    const char *newString = allocFromUTF8(other, len);
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF8(other, len);
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -321,8 +323,9 @@
 
 status_t String8::setTo(const char16_t* other, size_t len)
 {
+    const char *newString = allocFromUTF16(other, len);
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF16(other, len);
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -331,8 +334,9 @@
 
 status_t String8::setTo(const char32_t* other, size_t len)
 {
+    const char *newString = allocFromUTF32(other, len);
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF32(other, len);
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -368,6 +372,27 @@
     return real_append(other, otherLen);
 }
 
+status_t String8::appendFormat(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+
+    int result = NO_ERROR;
+    int n = vsnprintf(NULL, 0, fmt, ap);
+    if (n != 0) {
+        size_t oldLength = length();
+        char* buf = lockBuffer(oldLength + n);
+        if (buf) {
+            vsnprintf(buf + oldLength, n + 1, fmt, ap);
+        } else {
+            result = NO_MEMORY;
+        }
+    }
+
+    va_end(ap);
+    return result;
+}
+
 status_t String8::real_append(const char* other, size_t otherLen)
 {
     const size_t myLen = bytes();
@@ -407,15 +432,16 @@
     if (size != this->size()) {
         SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
             ->editResize(size+1);
-        if (buf) {
-            char* str = (char*)buf->data();
-            str[size] = 0;
-            mString = str;
-            return NO_ERROR;
+        if (! buf) {
+            return NO_MEMORY;
         }
+
+        char* str = (char*)buf->data();
+        str[size] = 0;
+        mString = str;
     }
-    
-    return NO_MEMORY;
+
+    return NO_ERROR;
 }
 
 ssize_t String8::find(const char* other, size_t start) const
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 2b1f490..f6c55e4 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -21,6 +21,7 @@
 #include <utils/Log.h>
 
 #include <cutils/sched_policy.h>
+#include <cutils/properties.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -57,13 +58,27 @@
 // ----------------------------------------------------------------------------
 
 /*
- * Create and run a new thead.
+ * Create and run a new thread.
  *
  * We create it "detached", so it cleans up after itself.
  */
 
 typedef void* (*android_pthread_entry)(void*);
 
+static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
+static bool gDoSchedulingGroup = true;
+
+static void checkDoSchedulingGroup(void) {
+    char buf[PROPERTY_VALUE_MAX];
+    int len = property_get("debug.sys.noschedgroups", buf, "");
+    if (len > 0) {
+        int temp;
+        if (sscanf(buf, "%d", &temp) == 1) {
+            gDoSchedulingGroup = temp == 0;
+        }
+    }
+}
+
 struct thread_data_t {
     thread_func_t   entryFunction;
     void*           userData;
@@ -79,6 +94,15 @@
         char * name = t->threadName;
         delete t;
         setpriority(PRIO_PROCESS, 0, prio);
+        pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+        if (gDoSchedulingGroup) {
+            if (prio >= ANDROID_PRIORITY_BACKGROUND) {
+                set_sched_policy(androidGetTid(), SP_BACKGROUND);
+            } else {
+                set_sched_policy(androidGetTid(), SP_FOREGROUND);
+            }
+        }
+        
         if (name) {
 #if defined(HAVE_PRCTL)
             // Mac OS doesn't have this, and we build libutil for the host too
@@ -287,9 +311,12 @@
     }
 
 #if defined(HAVE_PTHREADS)
-    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                      SP_BACKGROUND : SP_FOREGROUND)) {
-        return PERMISSION_DENIED;
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                                          SP_BACKGROUND : SP_FOREGROUND)) {
+            return PERMISSION_DENIED;
+        }
     }
 #endif
     
@@ -303,10 +330,13 @@
 #if defined(HAVE_PTHREADS)
     int lasterr = 0;
 
-    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_BACKGROUND);
-    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_FOREGROUND);
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_BACKGROUND);
+        } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_FOREGROUND);
+        }
     }
 
     if (rc) {
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 0322af7..289c826 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -108,13 +108,7 @@
 
 ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
 {
-    if (index > size())
-        return BAD_INDEX;
-    void* where = _grow(index, vector.size());
-    if (where) {
-        _do_copy(where, vector.arrayImpl(), vector.size());
-    }
-    return where ? index : (ssize_t)NO_MEMORY;
+    return insertArrayAt(vector.arrayImpl(), index, vector.size());
 }
 
 ssize_t VectorImpl::appendVector(const VectorImpl& vector)
@@ -122,6 +116,22 @@
     return insertVectorAt(vector, size());
 }
 
+ssize_t VectorImpl::insertArrayAt(const void* array, size_t index, size_t length)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, length);
+    if (where) {
+        _do_copy(where, array, length);
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+ssize_t VectorImpl::appendArray(const void* array, size_t length)
+{
+    return insertArrayAt(array, size(), length);
+}
+
 ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
 {
     return insertAt(0, index, numItems);
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
index 45f6c8b..16b219c 100644
--- a/libs/utils/ZipFileCRO.cpp
+++ b/libs/utils/ZipFileCRO.cpp
@@ -39,8 +39,8 @@
 }
 
 bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
-        int* pMethod, long* pUncompLen,
-        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+        int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
     ZipFileRO* zip = (ZipFileRO*)zipToken;
     ZipEntryRO entry = (ZipEntryRO)entryToken;
     return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index 6c701dd..2d53136 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -29,6 +29,22 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <assert.h>
+#include <unistd.h>
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
 
 using namespace android;
 
@@ -38,6 +54,7 @@
 #define kEOCDSignature      0x06054b50
 #define kEOCDLen            22
 #define kEOCDNumEntries     8               // offset to #of entries in file
+#define kEOCDSize           12              // size of the central directory
 #define kEOCDFileOffset     16              // offset to central directory
 
 #define kMaxCommentLen      65535           // longest possible in ushort
@@ -90,9 +107,8 @@
 status_t ZipFileRO::open(const char* zipFileName)
 {
     int fd = -1;
-    off_t length;
 
-    assert(mFileMap == NULL);
+    assert(mDirectoryMap == NULL);
 
     /*
      * Open and map the specified file.
@@ -103,172 +119,238 @@
         return NAME_NOT_FOUND;
     }
 
-    length = lseek(fd, 0, SEEK_END);
-    if (length < 0) {
+    mFileLength = lseek(fd, 0, SEEK_END);
+    if (mFileLength < kEOCDLen) {
         close(fd);
         return UNKNOWN_ERROR;
     }
 
-    mFileMap = new FileMap();
-    if (mFileMap == NULL) {
-        close(fd);
-        return NO_MEMORY;
+    if (mFileName != NULL) {
+        free(mFileName);
     }
-    if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
-        LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
-        close(fd);
-        return UNKNOWN_ERROR;
-    }
+    mFileName = strdup(zipFileName);
 
     mFd = fd;
 
     /*
-     * Got it mapped, verify it and create data structures for fast access.
+     * Find the Central Directory and store its size and number of entries.
+     */
+    if (!mapCentralDirectory()) {
+        goto bail;
+    }
+
+    /*
+     * Verify Central Directory and create data structures for fast access.
      */
     if (!parseZipArchive()) {
-        mFileMap->release();
-        mFileMap = NULL;
-        return UNKNOWN_ERROR;
+        goto bail;
     }
 
     return OK;
+
+bail:
+    free(mFileName);
+    mFileName = NULL;
+    close(fd);
+    return UNKNOWN_ERROR;
 }
 
 /*
  * Parse the Zip archive, verifying its contents and initializing internal
  * data structures.
  */
+bool ZipFileRO::mapCentralDirectory(void)
+{
+    size_t readAmount = kMaxEOCDSearch;
+    if (readAmount > (size_t) mFileLength)
+        readAmount = mFileLength;
+
+    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
+    if (scanBuf == NULL) {
+        LOGW("couldn't allocate scanBuf: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Make sure this is a Zip archive.
+     */
+    if (lseek(mFd, 0, SEEK_SET) != 0) {
+        LOGW("seek to start failed: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
+    if (actual != (ssize_t) sizeof(int32_t)) {
+        LOGI("couldn't read first signature from zip archive: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    {
+        unsigned int header = get4LE(scanBuf);
+        if (header == kEOCDSignature) {
+            LOGI("Found Zip archive, but it looks empty\n");
+            free(scanBuf);
+            return false;
+        } else if (header != kLFHSignature) {
+            LOGV("Not a Zip archive (found 0x%08x)\n", val);
+            free(scanBuf);
+            return false;
+        }
+    }
+
+    /*
+     * Perform the traditional EOCD snipe hunt.
+     *
+     * We're searching for the End of Central Directory magic number,
+     * which appears at the start of the EOCD block.  It's followed by
+     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
+     * need to read the last part of the file into a buffer, dig through
+     * it to find the magic number, parse some values out, and use those
+     * to determine the extent of the CD.
+     *
+     * We start by pulling in the last part of the file.
+     */
+    off_t searchStart = mFileLength - readAmount;
+
+    if (lseek(mFd, searchStart, SEEK_SET) != searchStart) {
+        LOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
+    if (actual != (ssize_t) readAmount) {
+        LOGW("Zip: read %zd failed: %s\n", readAmount, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Scan backward for the EOCD magic.  In an archive without a trailing
+     * comment, we'll find it on the first try.  (We may want to consider
+     * doing an initial minimal read; if we don't find it, retry with a
+     * second read as above.)
+     */
+    int i;
+    for (i = readAmount - kEOCDLen; i >= 0; i--) {
+        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
+            LOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        LOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
+        free(scanBuf);
+        return false;
+    }
+
+    off_t eocdOffset = searchStart + i;
+    const unsigned char* eocdPtr = scanBuf + i;
+
+    assert(eocdOffset < mFileLength);
+
+    /*
+     * Grab the CD offset and size, and the number of entries in the
+     * archive. After that, we can release our EOCD hunt buffer.
+     */
+    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
+    unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
+    unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
+    free(scanBuf);
+
+    // Verify that they look reasonable.
+    if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
+        LOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
+            (long) dirOffset, dirSize, (long) eocdOffset);
+        return false;
+    }
+    if (numEntries == 0) {
+        LOGW("empty archive?\n");
+        return false;
+    }
+
+    LOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
+        numEntries, dirSize, dirOffset);
+
+    mDirectoryMap = new FileMap();
+    if (mDirectoryMap == NULL) {
+        LOGW("Unable to create directory map: %s", strerror(errno));
+        return false;
+    }
+
+    if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
+        LOGW("Unable to map '%s' (%zd to %zd): %s\n", mFileName,
+                dirOffset, dirOffset + dirSize, strerror(errno));
+        return false;
+    }
+
+    mNumEntries = numEntries;
+    mDirectoryOffset = dirOffset;
+
+    return true;
+}
+
 bool ZipFileRO::parseZipArchive(void)
 {
-#define CHECK_OFFSET(_off) {                                                \
-        if ((unsigned int) (_off) >= maxOffset) {                           \
-            LOGE("ERROR: bad offset %u (max %d): %s\n",                     \
-                (unsigned int) (_off), maxOffset, #_off);                   \
-            goto bail;                                                      \
-        }                                                                   \
-    }
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
-    const unsigned char* ptr;
-    size_t length = mFileMap->getDataLength();
     bool result = false;
-    unsigned int i, numEntries, cdOffset;
-    unsigned int val;
-
-    /*
-     * The first 4 bytes of the file will either be the local header
-     * signature for the first file (kLFHSignature) or, if the archive doesn't
-     * have any files in it, the end-of-central-directory signature
-     * (kEOCDSignature).
-     */
-    val = get4LE(basePtr);
-    if (val == kEOCDSignature) {
-        LOGI("Found Zip archive, but it looks empty\n");
-        goto bail;
-    } else if (val != kLFHSignature) {
-        LOGV("Not a Zip archive (found 0x%08x)\n", val);
-        goto bail;
-    }
-
-    /*
-     * Find the EOCD.  We'll find it immediately unless they have a file
-     * comment.
-     */
-    ptr = basePtr + length - kEOCDLen;
-
-    while (ptr >= basePtr) {
-        if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)
-            break;
-        ptr--;
-    }
-    if (ptr < basePtr) {
-        LOGI("Could not find end-of-central-directory in Zip\n");
-        goto bail;
-    }
-
-    /*
-     * There are two interesting items in the EOCD block: the number of
-     * entries in the file, and the file offset of the start of the
-     * central directory.
-     *
-     * (There's actually a count of the #of entries in this file, and for
-     * all files which comprise a spanned archive, but for our purposes
-     * we're only interested in the current file.  Besides, we expect the
-     * two to be equivalent for our stuff.)
-     */
-    numEntries = get2LE(ptr + kEOCDNumEntries);
-    cdOffset = get4LE(ptr + kEOCDFileOffset);
-
-    /* valid offsets are [0,EOCD] */
-    unsigned int maxOffset;
-    maxOffset = (ptr - basePtr) +1;
-
-    LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
-    if (numEntries == 0 || cdOffset >= length) {
-        LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
-            numEntries, cdOffset, length);
-        goto bail;
-    }
+    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
+    size_t cdLength = mDirectoryMap->getDataLength();
+    int numEntries = mNumEntries;
 
     /*
      * Create hash table.  We have a minimum 75% load factor, possibly as
      * low as 50% after we round off to a power of 2.
      */
-    mNumEntries = numEntries;
-    mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));
-    mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);
+    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
+    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
 
     /*
      * Walk through the central directory, adding entries to the hash
      * table.
      */
-    ptr = basePtr + cdOffset;
-    for (i = 0; i < numEntries; i++) {
-        unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
-        const unsigned char* localHdr;
-        unsigned int hash;
-
+    const unsigned char* ptr = cdPtr;
+    for (int i = 0; i < numEntries; i++) {
         if (get4LE(ptr) != kCDESignature) {
             LOGW("Missed a central dir sig (at %d)\n", i);
             goto bail;
         }
-        if (ptr + kCDELen > basePtr + length) {
+        if (ptr + kCDELen > cdPtr + cdLength) {
             LOGW("Ran off the end (at %d)\n", i);
             goto bail;
         }
 
-        localHdrOffset = get4LE(ptr + kCDELocalOffset);
-        CHECK_OFFSET(localHdrOffset);
+        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset >= mDirectoryOffset) {
+            LOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
+            goto bail;
+        }
+
+        unsigned int fileNameLen, extraLen, commentLen, hash;
+
         fileNameLen = get2LE(ptr + kCDENameLen);
         extraLen = get2LE(ptr + kCDEExtraLen);
         commentLen = get2LE(ptr + kCDECommentLen);
 
-        //LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",
-        //    i, localHdrOffset, fileNameLen, extraLen, commentLen);
-        //LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);
-
         /* add the CDE filename to the hash table */
         hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
         addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
 
-        localHdr = basePtr + localHdrOffset;
-        if (get4LE(localHdr) != kLFHSignature) {
-            LOGW("Bad offset to local header: %d (at %d)\n",
-                localHdrOffset, i);
+        ptr += kCDELen + fileNameLen + extraLen + commentLen;
+        if ((size_t)(ptr - cdPtr) > cdLength) {
+            LOGW("bad CD advance (%d vs %zd) at entry %d\n",
+                (int) (ptr - cdPtr), cdLength, i);
             goto bail;
         }
-
-        ptr += kCDELen + fileNameLen + extraLen + commentLen;
-        CHECK_OFFSET(ptr - basePtr);
     }
-
+    LOGV("+++ zip good scan %d entries\n", numEntries);
     result = true;
 
 bail:
     return result;
-#undef CHECK_OFFSET
 }
 
-
 /*
  * Simple string hash function for non-null-terminated strings.
  */
@@ -315,7 +397,7 @@
             memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
         {
             /* match */
-            return (ZipEntryRO) (ent + kZipEntryAdj);
+            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
         }
 
         ent = (ent + 1) & (mHashTableSize-1);
@@ -354,20 +436,24 @@
  * Returns "false" if the offsets to the fields or the contents of the fields
  * appear to be bogus.
  */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
-    long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+    size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
 {
-    int ent = entryToIndex(entry);
+    bool ret = false;
+
+    const int ent = entryToIndex(entry);
     if (ent < 0)
         return false;
 
+    HashEntry hashEntry = mHashTable[ent];
+
     /*
      * Recover the start of the central directory entry from the filename
-     * pointer.
+     * pointer.  The filename is the first entry past the fixed-size data,
+     * so we can just subtract back from that.
      */
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
-    const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
-    size_t zipLength = mFileMap->getDataLength();
+    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
+    off_t cdOffset = mDirectoryOffset;
 
     ptr -= kCDELen;
 
@@ -380,48 +466,78 @@
     if (pCrc32 != NULL)
         *pCrc32 = get4LE(ptr + kCDECRC);
 
+    size_t compLen = get4LE(ptr + kCDECompLen);
+    if (pCompLen != NULL)
+        *pCompLen = compLen;
+    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
+    if (pUncompLen != NULL)
+        *pUncompLen = uncompLen;
+
     /*
-     * We need to make sure that the lengths are not so large that somebody
-     * trying to map the compressed or uncompressed data runs off the end
-     * of the mapped region.
+     * If requested, determine the offset of the start of the data.  All we
+     * have is the offset to the Local File Header, which is variable size,
+     * so we have to read the contents of the struct to figure out where
+     * the actual data starts.
+     *
+     * We also need to make sure that the lengths are not so large that
+     * somebody trying to map the compressed or uncompressed data runs
+     * off the end of the mapped region.
+     *
+     * Note we don't verify compLen/uncompLen if they don't request the
+     * dataOffset, because dataOffset is expensive to determine.  However,
+     * if they don't have the file offset, they're not likely to be doing
+     * anything with the contents.
      */
-    unsigned long localHdrOffset = get4LE(ptr + kCDELocalOffset);
-    if (localHdrOffset + kLFHLen >= zipLength) {
-        LOGE("ERROR: bad local hdr offset in zip\n");
-        return false;
-    }
-    const unsigned char* localHdr = basePtr + localHdrOffset;
-    off_t dataOffset = localHdrOffset + kLFHLen
-        + get2LE(localHdr + kLFHNameLen) + get2LE(localHdr + kLFHExtraLen);
-    if ((unsigned long) dataOffset >= zipLength) {
-        LOGE("ERROR: bad data offset in zip\n");
-        return false;
-    }
-
-    if (pCompLen != NULL) {
-        *pCompLen = get4LE(ptr + kCDECompLen);
-        if (*pCompLen < 0 || (size_t)(dataOffset + *pCompLen) >= zipLength) {
-            LOGE("ERROR: bad compressed length in zip\n");
-            return false;
-        }
-    }
-    if (pUncompLen != NULL) {
-        *pUncompLen = get4LE(ptr + kCDEUncompLen);
-        if (*pUncompLen < 0) {
-            LOGE("ERROR: negative uncompressed length in zip\n");
-            return false;
-        }
-        if (method == kCompressStored &&
-            (size_t)(dataOffset + *pUncompLen) >= zipLength)
-        {
-            LOGE("ERROR: bad uncompressed length in zip\n");
-            return false;
-        }
-    }
-
     if (pOffset != NULL) {
+        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset + kLFHLen >= cdOffset) {
+            LOGE("ERROR: bad local hdr offset in zip\n");
+            return false;
+        }
+
+        unsigned char lfhBuf[kLFHLen];
+        if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+            LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
+            return false;
+        }
+        ssize_t actual =
+            TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+        if (actual != sizeof(lfhBuf)) {
+            LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+            return false;
+        }
+
+        if (get4LE(lfhBuf) != kLFHSignature) {
+            LOGW("didn't find signature at start of lfh, offset=%ld (got 0x%08lx, expected 0x%08x)\n",
+                localHdrOffset, get4LE(lfhBuf), kLFHSignature);
+            return false;
+        }
+
+        off_t dataOffset = localHdrOffset + kLFHLen
+            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
+        if (dataOffset >= cdOffset) {
+            LOGW("bad data offset %ld in zip\n", (long) dataOffset);
+            return false;
+        }
+
+        /* check lengths */
+        if ((off_t)(dataOffset + compLen) > cdOffset) {
+            LOGW("bad compressed length in zip (%ld + %zd > %ld)\n",
+                (long) dataOffset, compLen, (long) cdOffset);
+            return false;
+        }
+
+        if (method == kCompressStored &&
+            (off_t)(dataOffset + uncompLen) > cdOffset)
+        {
+            LOGE("ERROR: bad uncompressed length in zip (%ld + %zd > %ld)\n",
+                (long) dataOffset, uncompLen, (long) cdOffset);
+            return false;
+        }
+
         *pOffset = dataOffset;
     }
+
     return true;
 }
 
@@ -457,14 +573,14 @@
      */
 
     FileMap* newMap;
-    long compLen;
+    size_t compLen;
     off_t offset;
 
     if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
         return NULL;
 
     newMap = new FileMap();
-    if (!newMap->create(mFileMap->getFileName(), mFd, offset, compLen, true)) {
+    if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
         newMap->release();
         return NULL;
     }
@@ -480,19 +596,26 @@
  */
 bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
 {
-    const int kSequentialMin = 32768;
+    const size_t kSequentialMin = 32768;
     bool result = false;
     int ent = entryToIndex(entry);
     if (ent < 0)
         return -1;
 
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
     int method;
-    long uncompLen, compLen;
+    size_t uncompLen, compLen;
     off_t offset;
+    const unsigned char* ptr;
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
+    FileMap* file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
+
+    ptr = (const unsigned char*) file->getDataPtr();
+
     /*
      * Experiment with madvise hint.  When we want to uncompress a file,
      * we pull some stuff out of the central dir entry and then hit a
@@ -507,17 +630,17 @@
      * pair of system calls are negated by a reduction in page faults.
      */
     if (compLen > kSequentialMin)
-        mFileMap->advise(FileMap::SEQUENTIAL);
+        file->advise(FileMap::SEQUENTIAL);
 
     if (method == kCompressStored) {
-        memcpy(buffer, basePtr + offset, uncompLen);
+        memcpy(buffer, ptr, uncompLen);
     } else {
-        if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
+        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
             goto bail;
     }
 
     if (compLen > kSequentialMin)
-        mFileMap->advise(FileMap::NORMAL);
+        file->advise(FileMap::NORMAL);
 
     result = true;
 
@@ -537,29 +660,34 @@
     if (ent < 0)
         return -1;
 
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
     int method;
-    long uncompLen, compLen;
+    size_t uncompLen, compLen;
     off_t offset;
+    const unsigned char* ptr;
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
-    if (method == kCompressStored) {
-        ssize_t actual;
+    const FileMap* file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
 
-        actual = write(fd, basePtr + offset, uncompLen);
+    ptr = (const unsigned char*) file->getDataPtr();
+
+    if (method == kCompressStored) {
+        ssize_t actual = write(fd, ptr, uncompLen);
         if (actual < 0) {
             LOGE("Write failed: %s\n", strerror(errno));
             goto bail;
-        } else if (actual != uncompLen) {
-            LOGE("Partial write during uncompress (%d of %ld)\n",
-                (int)actual, uncompLen);
+        } else if ((size_t) actual != uncompLen) {
+            LOGE("Partial write during uncompress (%zd of %zd)\n",
+                (size_t)actual, (size_t)uncompLen);
             goto bail;
         } else {
             LOGI("+++ successful write\n");
         }
     } else {
-        if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
+        if (!inflateBuffer(fd, ptr, uncompLen, compLen))
             goto bail;
     }
 
@@ -573,7 +701,7 @@
  * Uncompress "deflate" data from one buffer to another.
  */
 /*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
-    long uncompLen, long compLen)
+    size_t uncompLen, size_t compLen)
 {
     bool result = false;
     z_stream zstream;
@@ -582,7 +710,7 @@
     /*
      * Initialize the zlib stream struct.
      */
-	memset(&zstream, 0, sizeof(zstream));
+    memset(&zstream, 0, sizeof(zstream));
     zstream.zalloc = Z_NULL;
     zstream.zfree = Z_NULL;
     zstream.opaque = Z_NULL;
@@ -592,10 +720,10 @@
     zstream.avail_out = uncompLen;
     zstream.data_type = Z_UNKNOWN;
 
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
+    /*
+     * Use the undocumented "negative window bits" feature to tell zlib
+     * that there's no zlib header waiting for it.
+     */
     zerr = inflateInit2(&zstream, -MAX_WBITS);
     if (zerr != Z_OK) {
         if (zerr == Z_VERSION_ERROR) {
@@ -619,8 +747,8 @@
     }
 
     /* paranoia */
-    if ((long) zstream.total_out != uncompLen) {
-        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+    if (zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %zd)\n",
             zstream.total_out, uncompLen);
         goto z_bail;
     }
@@ -638,10 +766,10 @@
  * Uncompress "deflate" data from one buffer to an open file descriptor.
  */
 /*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
-    long uncompLen, long compLen)
+    size_t uncompLen, size_t compLen)
 {
     bool result = false;
-    const int kWriteBufSize = 32768;
+    const size_t kWriteBufSize = 32768;
     unsigned char writeBuf[kWriteBufSize];
     z_stream zstream;
     int zerr;
@@ -649,7 +777,7 @@
     /*
      * Initialize the zlib stream struct.
      */
-	memset(&zstream, 0, sizeof(zstream));
+    memset(&zstream, 0, sizeof(zstream));
     zstream.zalloc = Z_NULL;
     zstream.zfree = Z_NULL;
     zstream.opaque = Z_NULL;
@@ -659,10 +787,10 @@
     zstream.avail_out = sizeof(writeBuf);
     zstream.data_type = Z_UNKNOWN;
 
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
+    /*
+     * Use the undocumented "negative window bits" feature to tell zlib
+     * that there's no zlib header waiting for it.
+     */
     zerr = inflateInit2(&zstream, -MAX_WBITS);
     if (zerr != Z_OK) {
         if (zerr == Z_VERSION_ERROR) {
@@ -708,8 +836,8 @@
     assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
 
     /* paranoia */
-    if ((long) zstream.total_out != uncompLen) {
-        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+    if (zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %zd)\n",
             zstream.total_out, uncompLen);
         goto z_bail;
     }
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
new file mode 100644
index 0000000..725de9c
--- /dev/null
+++ b/libs/utils/tests/Android.mk
@@ -0,0 +1,45 @@
+# Build the unit tests.
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+ifneq ($(TARGET_SIMULATOR),true)
+
+# Build the unit tests.
+test_src_files := \
+	ObbFile_test.cpp \
+	PollLoop_test.cpp \
+	String8_test.cpp
+
+shared_libraries := \
+	libz \
+	liblog \
+	libcutils \
+	libutils \
+	libstlport
+
+static_libraries := \
+	libgtest \
+	libgtest_main
+
+c_includes := \
+    external/zlib \
+    external/icu4c/common \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport
+
+module_tags := eng tests
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+endif
diff --git a/libs/utils/tests/ObbFile_test.cpp b/libs/utils/tests/ObbFile_test.cpp
new file mode 100644
index 0000000..29bb70a
--- /dev/null
+++ b/libs/utils/tests/ObbFile_test.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "ObbFile_test"
+#include <utils/Log.h>
+#include <utils/ObbFile.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <fcntl.h>
+
+namespace android {
+
+#define TEST_FILENAME "/test.obb"
+
+class ObbFileTest : public testing::Test {
+protected:
+    sp<ObbFile> mObbFile;
+    char* mExternalStorage;
+    char* mFileName;
+
+    virtual void SetUp() {
+        mObbFile = new ObbFile();
+        mExternalStorage = getenv("EXTERNAL_STORAGE");
+
+        const int totalLen = strlen(mExternalStorage) + strlen(TEST_FILENAME) + 1;
+        mFileName = new char[totalLen];
+        snprintf(mFileName, totalLen, "%s%s", mExternalStorage, TEST_FILENAME);
+
+        int fd = ::open(mFileName, O_CREAT | O_TRUNC);
+        if (fd < 0) {
+            FAIL() << "Couldn't create " << mFileName << " for tests";
+        }
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(ObbFileTest, ReadFailure) {
+    EXPECT_FALSE(mObbFile->readFrom(-1))
+            << "No failure on invalid file descriptor";
+}
+
+TEST_F(ObbFileTest, WriteThenRead) {
+    const char* packageName = "com.example.obbfile";
+    const int32_t versionNum = 1;
+
+    mObbFile->setPackageName(String8(packageName));
+    mObbFile->setVersion(versionNum);
+
+    EXPECT_TRUE(mObbFile->writeTo(mFileName))
+            << "couldn't write to fake .obb file";
+
+    mObbFile = new ObbFile();
+
+    EXPECT_TRUE(mObbFile->readFrom(mFileName))
+            << "couldn't read from fake .obb file";
+
+    EXPECT_EQ(versionNum, mObbFile->getVersion())
+            << "version didn't come out the same as it went in";
+    const char* currentPackageName = mObbFile->getPackageName().string();
+    EXPECT_STREQ(packageName, currentPackageName)
+            << "package name didn't come out the same as it went in";
+}
+
+}
diff --git a/libs/utils/tests/PollLoop_test.cpp b/libs/utils/tests/PollLoop_test.cpp
new file mode 100644
index 0000000..02f1808
--- /dev/null
+++ b/libs/utils/tests/PollLoop_test.cpp
@@ -0,0 +1,370 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <utils/PollLoop.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "TestHelpers.h"
+
+// # of milliseconds to fudge stopwatch measurements
+#define TIMING_TOLERANCE_MS 25
+
+namespace android {
+
+class DelayedWake : public DelayedTask {
+    sp<PollLoop> mPollLoop;
+
+public:
+    DelayedWake(int delayMillis, const sp<PollLoop> pollLoop) :
+        DelayedTask(delayMillis), mPollLoop(pollLoop) {
+    }
+
+protected:
+    virtual void doTask() {
+        mPollLoop->wake();
+    }
+};
+
+class DelayedWriteSignal : public DelayedTask {
+    Pipe* mPipe;
+
+public:
+    DelayedWriteSignal(int delayMillis, Pipe* pipe) :
+        DelayedTask(delayMillis), mPipe(pipe) {
+    }
+
+protected:
+    virtual void doTask() {
+        mPipe->writeSignal();
+    }
+};
+
+class CallbackHandler {
+public:
+    void setCallback(const sp<PollLoop>& pollLoop, int fd, int events) {
+        pollLoop->setCallback(fd, events, staticHandler, this);
+    }
+
+protected:
+    virtual ~CallbackHandler() { }
+
+    virtual bool handler(int fd, int events) = 0;
+
+private:
+    static bool staticHandler(int fd, int events, void* data) {
+        return static_cast<CallbackHandler*>(data)->handler(fd, events);
+    }
+};
+
+class StubCallbackHandler : public CallbackHandler {
+public:
+    bool nextResult;
+    int callbackCount;
+
+    int fd;
+    int events;
+
+    StubCallbackHandler(bool nextResult) : nextResult(nextResult),
+            callbackCount(0), fd(-1), events(-1) {
+    }
+
+protected:
+    virtual bool handler(int fd, int events) {
+        callbackCount += 1;
+        this->fd = fd;
+        this->events = events;
+        return nextResult;
+    }
+};
+
+class PollLoopTest : public testing::Test {
+protected:
+    sp<PollLoop> mPollLoop;
+
+    virtual void SetUp() {
+        mPollLoop = new PollLoop(false);
+    }
+
+    virtual void TearDown() {
+        mPollLoop.clear();
+    }
+};
+
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeoutAndReturnsFalse) {
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout";
+    EXPECT_EQ(result, PollLoop::POLL_TIMEOUT)
+            << "pollOnce result should be POLL_TIMEOUT";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturnsTrue) {
+    mPollLoop->wake();
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because wake() was called before waiting";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because loop was awoken";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturnsTrue) {
+    sp<DelayedWake> delayedWake = new DelayedWake(100, mPollLoop);
+    delayedWake->run();
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal wake delay";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because loop was awoken";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturnsFalse) {
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(result, PollLoop::POLL_TIMEOUT)
+            << "pollOnce result should be POLL_TIMEOUT";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturnsFalse) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(result, PollLoop::POLL_TIMEOUT)
+            << "pollOnce result should be POLL_TIMEOUT";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not have been invoked because FD was not signalled";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturnsTrue) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    ASSERT_EQ(OK, pipe.writeSignal());
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked exactly once";
+    EXPECT_EQ(pipe.receiveFd, handler.fd)
+            << "callback should have received pipe fd as parameter";
+    EXPECT_EQ(POLL_IN, handler.events)
+            << "callback should have received POLL_IN as events";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturnsFalse) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout";
+    EXPECT_EQ(result, PollLoop::POLL_TIMEOUT)
+            << "pollOnce result should be POLL_TIMEOUT";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not have been invoked because FD was not signalled";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturnsTrue) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    pipe.writeSignal();
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_EQ(OK, pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked exactly once";
+    EXPECT_EQ(pipe.receiveFd, handler.fd)
+            << "callback should have received pipe fd as parameter";
+    EXPECT_EQ(POLL_IN, handler.events)
+            << "callback should have received POLL_IN as events";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturnsTrue) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+    sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+    delayedWriteSignal->run();
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_EQ(OK, pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal signal delay";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked exactly once";
+    EXPECT_EQ(pipe.receiveFd, handler.fd)
+            << "callback should have received pipe fd as parameter";
+    EXPECT_EQ(POLL_IN, handler.events)
+            << "callback should have received POLL_IN as events";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+    pipe.writeSignal(); // would cause FD to be considered signalled
+    mPollLoop->removeCallback(pipe.receiveFd);
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_EQ(OK, pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout because FD was no longer registered";
+    EXPECT_EQ(result, PollLoop::POLL_TIMEOUT)
+            << "pollOnce result should be POLL_TIMEOUT";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not be invoked";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
+    Pipe pipe;
+    StubCallbackHandler handler(false);
+
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    // First loop: Callback is registered and FD is signalled.
+    pipe.writeSignal();
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_EQ(OK, pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal zero because FD was already signalled";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because FD was signalled";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should be invoked";
+
+    // Second loop: Callback is no longer registered and FD is signalled.
+    pipe.writeSignal();
+
+    stopWatch.reset();
+    result = mPollLoop->pollOnce(0);
+    elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_EQ(OK, pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal zero because timeout was zero";
+    EXPECT_EQ(result, PollLoop::POLL_TIMEOUT)
+            << "pollOnce result should be POLL_TIMEOUT";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should not be invoked this time";
+}
+
+TEST_F(PollLoopTest, RemoveCallback_WhenCallbackNotAdded_ReturnsFalse) {
+    bool result = mPollLoop->removeCallback(1);
+
+    EXPECT_FALSE(result)
+            << "removeCallback should return false because FD not registered";
+}
+
+TEST_F(PollLoopTest, RemoveCallback_WhenCallbackAddedThenRemovedTwice_ReturnsTrueFirstTimeAndReturnsFalseSecondTime) {
+    Pipe pipe;
+    StubCallbackHandler handler(false);
+    handler.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+
+    // First time.
+    bool result = mPollLoop->removeCallback(pipe.receiveFd);
+
+    EXPECT_TRUE(result)
+            << "removeCallback should return true first time because FD was registered";
+
+    // Second time.
+    result = mPollLoop->removeCallback(pipe.receiveFd);
+
+    EXPECT_FALSE(result)
+            << "removeCallback should return false second time because FD was no longer registered";
+}
+
+TEST_F(PollLoopTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
+    Pipe pipe;
+    StubCallbackHandler handler1(true);
+    StubCallbackHandler handler2(true);
+
+    handler1.setCallback(mPollLoop, pipe.receiveFd, POLL_IN);
+    handler2.setCallback(mPollLoop, pipe.receiveFd, POLL_IN); // replace it
+    pipe.writeSignal(); // would cause FD to be considered signalled
+
+    StopWatch stopWatch("pollOnce");
+    int32_t result = mPollLoop->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    ASSERT_EQ(OK, pipe.readSignal())
+            << "signal should actually have been written";
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. zero because FD was already signalled";
+    EXPECT_EQ(result, PollLoop::POLL_CALLBACK)
+            << "pollOnce result should be POLL_CALLBACK because FD was signalled";
+    EXPECT_EQ(0, handler1.callbackCount)
+            << "original handler callback should not be invoked because it was replaced";
+    EXPECT_EQ(1, handler2.callbackCount)
+            << "replacement handler callback should be invoked";
+}
+
+
+} // namespace android
diff --git a/libs/utils/tests/String8_test.cpp b/libs/utils/tests/String8_test.cpp
new file mode 100644
index 0000000..c42c68d
--- /dev/null
+++ b/libs/utils/tests/String8_test.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#define LOG_TAG "String8_test"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+class String8Test : public testing::Test {
+protected:
+    virtual void SetUp() {
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(String8Test, Cstr) {
+    String8 tmp("Hello, world!");
+
+    EXPECT_STREQ(tmp.string(), "Hello, world!");
+}
+
+TEST_F(String8Test, OperatorPlus) {
+    String8 src1("Hello, ");
+
+    // Test adding String8 + const char*
+    const char* ccsrc2 = "world!";
+    String8 dst1 = src1 + ccsrc2;
+    EXPECT_STREQ(dst1.string(), "Hello, world!");
+    EXPECT_STREQ(src1.string(), "Hello, ");
+    EXPECT_STREQ(ccsrc2, "world!");
+
+    // Test adding String8 + String8
+    String8 ssrc2("world!");
+    String8 dst2 = src1 + ssrc2;
+    EXPECT_STREQ(dst2.string(), "Hello, world!");
+    EXPECT_STREQ(src1.string(), "Hello, ");
+    EXPECT_STREQ(ssrc2.string(), "world!");
+}
+
+TEST_F(String8Test, OperatorPlusEquals) {
+    String8 src1("My voice");
+
+    // Testing String8 += String8
+    String8 src2(" is my passport.");
+    src1 += src2;
+    EXPECT_STREQ(src1.string(), "My voice is my passport.");
+    EXPECT_STREQ(src2.string(), " is my passport.");
+
+    // Adding const char* to the previous string.
+    const char* src3 = " Verify me.";
+    src1 += src3;
+    EXPECT_STREQ(src1.string(), "My voice is my passport. Verify me.");
+    EXPECT_STREQ(src2.string(), " is my passport.");
+    EXPECT_STREQ(src3, " Verify me.");
+}
+
+}
diff --git a/libs/utils/tests/TestHelpers.h b/libs/utils/tests/TestHelpers.h
new file mode 100644
index 0000000..d8e985e
--- /dev/null
+++ b/libs/utils/tests/TestHelpers.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef TESTHELPERS_H
+#define TESTHELPERS_H
+
+#include <utils/threads.h>
+
+namespace android {
+
+class Pipe {
+public:
+    int sendFd;
+    int receiveFd;
+
+    Pipe() {
+        int fds[2];
+        ::pipe(fds);
+
+        receiveFd = fds[0];
+        sendFd = fds[1];
+    }
+
+    ~Pipe() {
+        if (sendFd != -1) {
+            ::close(sendFd);
+        }
+
+        if (receiveFd != -1) {
+            ::close(receiveFd);
+        }
+    }
+
+    status_t writeSignal() {
+        ssize_t nWritten = ::write(sendFd, "*", 1);
+        return nWritten == 1 ? 0 : -errno;
+    }
+
+    status_t readSignal() {
+        char buf[1];
+        ssize_t nRead = ::read(receiveFd, buf, 1);
+        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
+    }
+};
+
+class DelayedTask : public Thread {
+    int mDelayMillis;
+
+public:
+    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
+
+protected:
+    virtual ~DelayedTask() { }
+
+    virtual void doTask() = 0;
+
+    virtual bool threadLoop() {
+        usleep(mDelayMillis * 1000);
+        doTask();
+        return false;
+    }
+};
+
+} // namespace android
+
+#endif // TESTHELPERS_H
diff --git a/opengl/include/EGL/egl.h b/opengl/include/EGL/egl.h
index c269976..99ea342 100644
--- a/opengl/include/EGL/egl.h
+++ b/opengl/include/EGL/egl.h
@@ -1,7 +1,7 @@
 /* -*- mode: c; tab-width: 8; -*- */
 /* vi: set sw=4 ts=8: */
 /* Reference version of egl.h for EGL 1.4.
- * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
  */
 
 /*
@@ -109,7 +109,6 @@
 #define EGL_NATIVE_RENDERABLE		0x302D
 #define EGL_NATIVE_VISUAL_ID		0x302E
 #define EGL_NATIVE_VISUAL_TYPE		0x302F
-#define EGL_PRESERVED_RESOURCES		0x3030
 #define EGL_SAMPLES			0x3031
 #define EGL_SAMPLE_BUFFERS		0x3032
 #define EGL_SURFACE_TYPE		0x3033
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 545fd0e..1ffcd56 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -6,7 +6,7 @@
 #endif
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2007-2010 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -34,8 +34,8 @@
 
 /* Header file version number */
 /* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $ */
-#define EGL_EGLEXT_VERSION 3
+/* $Revision: 11249 $ on $Date: 2010-05-05 09:54:28 -0700 (Wed, 05 May 2010) $ */
+#define EGL_EGLEXT_VERSION 5
 
 #ifndef EGL_KHR_config_attribs
 #define EGL_KHR_config_attribs 1
@@ -120,6 +120,36 @@
 #define EGL_GL_RENDERBUFFER_KHR			0x30B9	/* eglCreateImageKHR target */
 #endif
 
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+
+typedef void* EGLSyncKHR;
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+
+#define EGL_SYNC_STATUS_KHR			0x30F1
+#define EGL_SIGNALED_KHR			0x30F2
+#define EGL_UNSIGNALED_KHR			0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR			0x30F5
+#define EGL_CONDITION_SATISFIED_KHR		0x30F6
+#define EGL_SYNC_TYPE_KHR			0x30F7
+#define EGL_SYNC_REUSABLE_KHR			0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR		0x0001	/* eglClientWaitSyncKHR <flags> bitfield */
+#define EGL_FOREVER_KHR				0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR				((EGLSyncKHR)0)
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+
 #ifndef EGL_KHR_image_base
 #define EGL_KHR_image_base 1
 /* Most interfaces defined by EGL_KHR_image_pixmap above */
@@ -131,6 +161,67 @@
 /* Interfaces defined by EGL_KHR_image above */
 #endif
 
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG		0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG		0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG		0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG		0x3103
+#endif
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV	0x30E6
+#define EGL_SYNC_STATUS_NV			0x30E7
+#define EGL_SIGNALED_NV				0x30E8
+#define EGL_UNSIGNALED_NV			0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV		0x0001
+#define EGL_FOREVER_NV				0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV			0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV			0x30EB
+#define EGL_CONDITION_SATISFIED_NV		0x30EC
+#define EGL_SYNC_TYPE_NV			0x30ED
+#define EGL_SYNC_CONDITION_NV			0x30EE
+#define EGL_SYNC_FENCE_NV			0x30EF
+#define EGL_NO_SYNC_NV				((EGLSyncNV)0)
+typedef void* EGLSyncNV;
+typedef unsigned long long EGLTimeNV;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
+EGLBoolean eglFenceNV (EGLSyncNV sync);
+EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR	0x30F0
+#define EGL_SYNC_CONDITION_KHR			0x30F8
+#define EGL_SYNC_FENCE_KHR			0x30F9
+#endif
 
 #ifndef EGL_ANDROID_image_native_buffer
 #define EGL_ANDROID_image_native_buffer 1
@@ -138,14 +229,6 @@
 #define EGL_NATIVE_BUFFER_ANDROID       0x3140  /* eglCreateImageKHR target */
 #endif
 
-#ifndef EGL_ANDROID_get_render_buffer
-#define EGL_ANDROID_get_render_buffer 1
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLClientBuffer EGLAPIENTRY eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw);
-#endif
-typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETRENDERBUFFERANDROIDPROC) (EGLDisplay dpy, EGLSurface draw);
-#endif
-
 #ifndef EGL_ANDROID_swap_rectangle
 #define EGL_ANDROID_swap_rectangle 1
 #ifdef EGL_EGLEXT_PROTOTYPES
@@ -154,7 +237,6 @@
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSWAPRECTANGLEANDROIDPROC) (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height);
 #endif
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h
index 53e9e61..25d7697 100644
--- a/opengl/include/EGL/eglplatform.h
+++ b/opengl/include/EGL/eglplatform.h
@@ -25,7 +25,7 @@
 */
 
 /* Platform-specific types and definitions for egl.h
- * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ * $Revision: 9724 $ on $Date: 2009-12-02 02:05:33 -0800 (Wed, 02 Dec 2009) $
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
@@ -50,8 +50,10 @@
 #define EGLAPI KHRONOS_APICALL
 #endif
 
+#ifndef EGLAPIENTRY
 #define EGLAPIENTRY  KHRONOS_APIENTRY
-#define EGLAPIENTRYP KHRONOS_APIENTRY*
+#endif
+#define EGLAPIENTRYP EGLAPIENTRY*
 
 /* The types NativeDisplayType, NativeWindowType, and NativePixmapType
  * are aliases of window-system-dependent types, such as X Display * or
@@ -89,10 +91,11 @@
 
 #elif defined(ANDROID)
 
-struct android_native_window_t;
+#include <android/native_window.h>
+
 struct egl_native_pixmap_t;
 
-typedef struct android_native_window_t* EGLNativeWindowType;
+typedef struct ANativeWindow*           EGLNativeWindowType;
 typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
 typedef void*                           EGLNativeDisplayType;
 
diff --git a/opengl/include/GLES/gl.h b/opengl/include/GLES/gl.h
index 2e8b971..5b8d85a 100644
--- a/opengl/include/GLES/gl.h
+++ b/opengl/include/GLES/gl.h
@@ -1,7 +1,7 @@
 #ifndef __gl_h_
 #define __gl_h_
 
-/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+/* $Revision: 10601 $ on $Date:: 2010-03-04 22:15:27 -0800 #$ */
 
 #include <GLES/glplatform.h>
 
@@ -15,6 +15,7 @@
  */
 
 typedef void             GLvoid;
+typedef char             GLchar;
 typedef unsigned int     GLenum;
 typedef unsigned char    GLboolean;
 typedef unsigned int     GLbitfield;
@@ -678,7 +679,7 @@
 GL_API void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params);
 GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params);
 GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params);
-GL_API void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
+GL_API void GL_APIENTRY glGetPointerv (GLenum pname, GLvoid **params);
 GL_API const GLubyte * GL_APIENTRY glGetString (GLenum name);
 GL_API void GL_APIENTRY glGetTexEnviv (GLenum env, GLenum pname, GLint *params);
 GL_API void GL_APIENTRY glGetTexEnvxv (GLenum env, GLenum pname, GLfixed *params);
diff --git a/opengl/include/GLES/glext.h b/opengl/include/GLES/glext.h
index a8fe2e9..a5b3ead 100644
--- a/opengl/include/GLES/glext.h
+++ b/opengl/include/GLES/glext.h
@@ -1,7 +1,7 @@
 #ifndef __glext_h_
 #define __glext_h_
 
-/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+/* $Revision: 10965 $ on $Date:: 2010-04-09 02:11:29 -0700 #$ */
 
 #ifdef __cplusplus
 extern "C" {
@@ -68,6 +68,11 @@
 typedef void* GLeglImageOES;
 #endif
 
+/* GL_OES_element_index_uint */
+#ifndef GL_OES_element_index_uint
+#define GL_UNSIGNED_INT                                         0x1405
+#endif
+
 /* GL_OES_fixed_point */
 #ifndef GL_OES_fixed_point
 #define GL_FIXED_OES                                            0x140C
@@ -201,6 +206,16 @@
 #define GL_MIRRORED_REPEAT_OES                                  0x8370
 #endif
 
+/* GL_OES_vertex_array_object */
+#ifndef GL_OES_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_OES                             0x85B5
+#endif
+
+/* GL_OES_texture_external */
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES                                 0x8D65
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension tokens
  *------------------------------------------------------------------------*/
@@ -219,15 +234,191 @@
 #endif
 
 /*------------------------------------------------------------------------*
+ * APPLE extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_texture_2D_limited_npot */
+/* No new tokens introduced by this extension. */
+
+/*------------------------------------------------------------------------*
  * EXT extension tokens
  *------------------------------------------------------------------------*/
 
+/* GL_EXT_blend_minmax */
+#ifndef GL_EXT_blend_minmax
+#define GL_MIN_EXT                                              0x8007
+#define GL_MAX_EXT                                              0x8008
+#endif
+
+/* GL_EXT_discard_framebuffer */
+#ifndef GL_EXT_discard_framebuffer
+#define GL_COLOR_EXT                                            0x1800
+#define GL_DEPTH_EXT                                            0x1801
+#define GL_STENCIL_EXT                                          0x1802
+#endif
+
+/* GL_EXT_multi_draw_arrays */
+/* No new tokens introduced by this extension. */
+
+/* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_read_format_bgra
+#define GL_BGRA_EXT                                             0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT                       0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT                       0x8366
+#endif
+
 /* GL_EXT_texture_filter_anisotropic */
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
 #endif
 
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_BGRA_EXT                                             0x80E1
+#endif
+
+/* GL_EXT_texture_lod_bias */
+#ifndef GL_EXT_texture_lod_bias
+#define GL_MAX_TEXTURE_LOD_BIAS_EXT                             0x84FD
+#define GL_TEXTURE_FILTER_CONTROL_EXT                           0x8500
+#define GL_TEXTURE_LOD_BIAS_EXT                                 0x8501
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_read_format */
+#ifndef GL_IMG_read_format
+#define GL_BGRA_IMG                                             0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG                       0x8365
+#endif
+
+/* GL_IMG_texture_compression_pvrtc */
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG                      0x8C00
+#define GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG                      0x8C01
+#define GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG                     0x8C02
+#define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
+#endif
+
+/* GL_IMG_texture_env_enhanced_fixed_function */
+#ifndef GL_IMG_texture_env_enhanced_fixed_function
+#define GL_MODULATE_COLOR_IMG                                   0x8C04
+#define GL_RECIP_ADD_SIGNED_ALPHA_IMG                           0x8C05
+#define GL_TEXTURE_ALPHA_MODULATE_IMG                           0x8C06
+#define GL_FACTOR_ALPHA_MODULATE_IMG                            0x8C07
+#define GL_FRAGMENT_ALPHA_MODULATE_IMG                          0x8C08
+#define GL_ADD_BLEND_IMG                                        0x8C09
+#define GL_DOT3_RGBA_IMG                                        0x86AF
+#endif
+
+/* GL_IMG_user_clip_plane */
+#ifndef GL_IMG_user_clip_plane
+#define GL_CLIP_PLANE0_IMG                                      0x3000
+#define GL_CLIP_PLANE1_IMG                                      0x3001
+#define GL_CLIP_PLANE2_IMG                                      0x3002
+#define GL_CLIP_PLANE3_IMG                                      0x3003
+#define GL_CLIP_PLANE4_IMG                                      0x3004
+#define GL_CLIP_PLANE5_IMG                                      0x3005
+#define GL_MAX_CLIP_PLANES_IMG                                  0x0D32
+#endif
+
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_RENDERBUFFER_SAMPLES_IMG                             0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG               0x9134
+#define GL_MAX_SAMPLES_IMG                                      0x9135
+#define GL_TEXTURE_SAMPLES_IMG                                  0x9136
+#endif
+
+/*------------------------------------------------------------------------*
+ * NV extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_NV_fence */
+#ifndef GL_NV_fence
+#define GL_ALL_COMPLETED_NV                                     0x84F2
+#define GL_FENCE_STATUS_NV                                      0x84F3
+#define GL_FENCE_CONDITION_NV                                   0x84F4
+#endif
+
+/*------------------------------------------------------------------------*
+ * QCOM extension tokens
+ *------------------------------------------------------------------------*/
+
+/* GL_QCOM_driver_control */
+/* No new tokens introduced by this extension. */
+
+/* GL_QCOM_extended_get */
+#ifndef GL_QCOM_extended_get
+#define GL_TEXTURE_WIDTH_QCOM                                   0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM                                  0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM                                   0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM                         0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM                                  0x8BD6
+#define GL_TEXTURE_TYPE_QCOM                                    0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM                             0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM                              0x8BD9
+#define GL_TEXTURE_TARGET_QCOM                                  0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM                            0x8BDB
+#define GL_STATE_RESTORE                                        0x8BDC
+#endif
+
+/* GL_QCOM_extended_get2 */
+/* No new tokens introduced by this extension. */
+
+/* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_PERFMON_GLOBAL_MODE_QCOM                             0x8FA0
+#endif
+
+/* GL_QCOM_writeonly_rendering */
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_WRITEONLY_RENDERING_QCOM                             0x8823
+#endif
+
+/* GL_QCOM_tiled_rendering */
+#ifndef GL_QCOM_tiled_rendering
+#define GL_COLOR_BUFFER_BIT0_QCOM                               0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM                               0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM                               0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM                               0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM                               0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM                               0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM                               0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM                               0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM                               0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM                               0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM                               0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM                               0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM                               0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM                               0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM                               0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM                               0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM                             0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM                             0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM                             0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM                             0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM                             0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM                             0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM                             0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM                             0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM                         0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM                         0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM                         0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM                         0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM                         0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM                         0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM                         0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM                         0x80000000
+#endif
+
+/*------------------------------------------------------------------------*
+ * End of extension tokens, start of corresponding extension functions
+ *------------------------------------------------------------------------*/
+
 /*------------------------------------------------------------------------*
  * OES extension functions
  *------------------------------------------------------------------------*/
@@ -456,11 +647,11 @@
 #ifdef GL_GLEXT_PROTOTYPES
 GL_API void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
 GL_API GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
-GL_API void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void** params);
+GL_API void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid ** params);
 #endif
 typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
 typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
-typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid ** params);
 #endif
 
 /* GL_OES_matrix_get */
@@ -576,6 +767,26 @@
 #define GL_OES_texture_mirrored_repeat 1
 #endif
 
+/* GL_OES_vertex_array_object */
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glBindVertexArrayOES (GLuint array);
+GL_API void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays);
+GL_API void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays);
+GL_API GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array);
+#endif
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
+#endif
+
+/* GL_OES_texture_external */
+#ifndef GL_OES_texture_external
+#define GL_OES_texture_external 1
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension functions
  *------------------------------------------------------------------------*/
@@ -591,14 +802,207 @@
 #endif
 
 /*------------------------------------------------------------------------*
+ * APPLE extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_APPLE_texture_2D_limited_npot */
+#ifndef GL_APPLE_texture_2D_limited_npot
+#define GL_APPLE_texture_2D_limited_npot 1
+#endif
+
+/*------------------------------------------------------------------------*
  * EXT extension functions
  *------------------------------------------------------------------------*/
 
+/* GL_EXT_blend_minmax */
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#endif
+
+/* GL_EXT_discard_framebuffer */
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+
+/* GL_EXT_multi_draw_arrays */
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+GL_API void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+/* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#endif
+
 /* GL_EXT_texture_filter_anisotropic */
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_EXT_texture_filter_anisotropic 1
 #endif
 
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_EXT_texture_format_BGRA8888 1
+#endif
+
+/* GL_EXT_texture_lod_bias */
+#ifndef GL_EXT_texture_lod_bias
+#define GL_EXT_texture_lod_bias 1
+#endif
+
+/*------------------------------------------------------------------------*
+ * IMG extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_IMG_read_format */
+#ifndef GL_IMG_read_format
+#define GL_IMG_read_format 1
+#endif
+
+/* GL_IMG_texture_compression_pvrtc */
+#ifndef GL_IMG_texture_compression_pvrtc
+#define GL_IMG_texture_compression_pvrtc 1
+#endif
+
+/* GL_IMG_texture_env_enhanced_fixed_function */
+#ifndef GL_IMG_texture_env_enhanced_fixed_function
+#define GL_IMG_texture_env_enhanced_fixed_function 1
+#endif
+
+/* GL_IMG_user_clip_plane */
+#ifndef GL_IMG_user_clip_plane
+#define GL_IMG_user_clip_plane 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glClipPlanefIMG (GLenum p, const GLfloat *eqn);
+GL_API void GL_APIENTRY glClipPlanexIMG (GLenum p, const GLfixed *eqn);
+#endif
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEFIMGPROC) (GLenum p, const GLfloat *eqn);
+typedef void (GL_APIENTRYP PFNGLCLIPPLANEXIMGPROC) (GLenum p, const GLfixed *eqn);
+#endif
+
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_API void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
+/*------------------------------------------------------------------------*
+ * NV extension functions
+ *------------------------------------------------------------------------*/
+
+/* NV_fence */
+#ifndef GL_NV_fence
+#define GL_NV_fence 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences);
+GL_API void GL_APIENTRY glGenFencesNV (GLsizei n, GLuint *fences);
+GL_API GLboolean GL_APIENTRY glIsFenceNV (GLuint fence);
+GL_API GLboolean GL_APIENTRY glTestFenceNV (GLuint fence);
+GL_API void GL_APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glFinishFenceNV (GLuint fence);
+GL_API void GL_APIENTRY glSetFenceNV (GLuint fence, GLenum condition);
+#endif
+typedef void (GL_APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences);
+typedef void (GL_APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences);
+typedef GLboolean (GL_APIENTRYP PFNGLISFENCENVPROC) (GLuint fence);
+typedef GLboolean (GL_APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence);
+typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
+#endif
+
+/*------------------------------------------------------------------------*
+ * QCOM extension functions
+ *------------------------------------------------------------------------*/
+
+/* GL_QCOM_driver_control */
+#ifndef GL_QCOM_driver_control
+#define GL_QCOM_driver_control 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
+GL_API void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+GL_API void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
+GL_API void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
+#endif
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
+typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
+#endif
+
+/* GL_QCOM_extended_get */
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures);
+GL_API void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+GL_API void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+GL_API void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+GL_API void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+GL_API void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param);
+GL_API void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+GL_API void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params);
+#endif
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params);
+#endif
+
+/* GL_QCOM_extended_get2 */
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+GL_API void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GL_API GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program);
+GL_API void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+
+/* GL_QCOM_perfmon_global_mode */
+#ifndef GL_QCOM_perfmon_global_mode
+#define GL_QCOM_perfmon_global_mode 1
+#endif
+
+/* GL_QCOM_writeonly_rendering */
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#endif
+
+/* GL_QCOM_tiled_rendering */
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_API void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+GL_API void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
+#endif
+typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/opengl/include/GLES/glplatform.h b/opengl/include/GLES/glplatform.h
index 198e679..2db6ee2 100644
--- a/opengl/include/GLES/glplatform.h
+++ b/opengl/include/GLES/glplatform.h
@@ -1,7 +1,7 @@
 #ifndef __glplatform_h_
 #define __glplatform_h_
 
-/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+/* $Revision: 10601 $ on $Date:: 2010-03-04 22:15:27 -0800 #$ */
 
 /*
  * This document is licensed under the SGI Free Software B License Version
@@ -9,7 +9,6 @@
  */
 
 /* Platform-specific types and definitions for OpenGL ES 1.X  gl.h
- * Last modified on 2008/12/19
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
@@ -24,10 +23,8 @@
 #define GL_API      KHRONOS_APICALL
 #endif
 
-#if defined(ANDROID)
-
+#ifndef GL_APIENTRY
 #define GL_APIENTRY KHRONOS_APIENTRY
-
 #endif
 
 #endif /* __glplatform_h_ */
diff --git a/opengl/include/GLES2/gl2.h b/opengl/include/GLES2/gl2.h
index 0182a67..e1d3b87 100644
--- a/opengl/include/GLES2/gl2.h
+++ b/opengl/include/GLES2/gl2.h
@@ -1,7 +1,7 @@
 #ifndef __gl2_h_
 #define __gl2_h_
 
-/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */
+/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
 
 #include <GLES2/gl2platform.h>
 
@@ -19,6 +19,7 @@
  *-----------------------------------------------------------------------*/
 
 typedef void             GLvoid;
+typedef char             GLchar;
 typedef unsigned int     GLenum;
 typedef unsigned char    GLboolean;
 typedef unsigned int     GLbitfield;
@@ -472,7 +473,7 @@
 
 GL_APICALL void         GL_APIENTRY glActiveTexture (GLenum texture);
 GL_APICALL void         GL_APIENTRY glAttachShader (GLuint program, GLuint shader);
-GL_APICALL void         GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const char* name);
+GL_APICALL void         GL_APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar* name);
 GL_APICALL void         GL_APIENTRY glBindBuffer (GLenum target, GLuint buffer);
 GL_APICALL void         GL_APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
 GL_APICALL void         GL_APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer);
@@ -482,8 +483,8 @@
 GL_APICALL void         GL_APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
 GL_APICALL void         GL_APIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor);
 GL_APICALL void         GL_APIENTRY glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
-GL_APICALL void         GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void* data, GLenum usage);
-GL_APICALL void         GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void* data);
+GL_APICALL void         GL_APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage);
+GL_APICALL void         GL_APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data);
 GL_APICALL GLenum       GL_APIENTRY glCheckFramebufferStatus (GLenum target);
 GL_APICALL void         GL_APIENTRY glClear (GLbitfield mask);
 GL_APICALL void         GL_APIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
@@ -491,8 +492,8 @@
 GL_APICALL void         GL_APIENTRY glClearStencil (GLint s);
 GL_APICALL void         GL_APIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
 GL_APICALL void         GL_APIENTRY glCompileShader (GLuint shader);
-GL_APICALL void         GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data);
-GL_APICALL void         GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data);
+GL_APICALL void         GL_APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void         GL_APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data);
 GL_APICALL void         GL_APIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
 GL_APICALL void         GL_APIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
 GL_APICALL GLuint       GL_APIENTRY glCreateProgram (void);
@@ -511,7 +512,7 @@
 GL_APICALL void         GL_APIENTRY glDisable (GLenum cap);
 GL_APICALL void         GL_APIENTRY glDisableVertexAttribArray (GLuint index);
 GL_APICALL void         GL_APIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count);
-GL_APICALL void         GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void* indices);
+GL_APICALL void         GL_APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices);
 GL_APICALL void         GL_APIENTRY glEnable (GLenum cap);
 GL_APICALL void         GL_APIENTRY glEnableVertexAttribArray (GLuint index);
 GL_APICALL void         GL_APIENTRY glFinish (void);
@@ -524,10 +525,10 @@
 GL_APICALL void         GL_APIENTRY glGenFramebuffers (GLsizei n, GLuint* framebuffers);
 GL_APICALL void         GL_APIENTRY glGenRenderbuffers (GLsizei n, GLuint* renderbuffers);
 GL_APICALL void         GL_APIENTRY glGenTextures (GLsizei n, GLuint* textures);
-GL_APICALL void         GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
-GL_APICALL void         GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name);
+GL_APICALL void         GL_APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
+GL_APICALL void         GL_APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name);
 GL_APICALL void         GL_APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders);
-GL_APICALL int          GL_APIENTRY glGetAttribLocation (GLuint program, const char* name);
+GL_APICALL int          GL_APIENTRY glGetAttribLocation (GLuint program, const GLchar* name);
 GL_APICALL void         GL_APIENTRY glGetBooleanv (GLenum pname, GLboolean* params);
 GL_APICALL void         GL_APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint* params);
 GL_APICALL GLenum       GL_APIENTRY glGetError (void);
@@ -535,21 +536,21 @@
 GL_APICALL void         GL_APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint* params);
 GL_APICALL void         GL_APIENTRY glGetIntegerv (GLenum pname, GLint* params);
 GL_APICALL void         GL_APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint* params);
-GL_APICALL void         GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, char* infolog);
+GL_APICALL void         GL_APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog);
 GL_APICALL void         GL_APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint* params);
 GL_APICALL void         GL_APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint* params);
-GL_APICALL void         GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog);
+GL_APICALL void         GL_APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog);
 GL_APICALL void         GL_APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision);
-GL_APICALL void         GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, char* source);
+GL_APICALL void         GL_APIENTRY glGetShaderSource (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source);
 GL_APICALL const GLubyte* GL_APIENTRY glGetString (GLenum name);
 GL_APICALL void         GL_APIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat* params);
 GL_APICALL void         GL_APIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint* params);
 GL_APICALL void         GL_APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat* params);
 GL_APICALL void         GL_APIENTRY glGetUniformiv (GLuint program, GLint location, GLint* params);
-GL_APICALL int          GL_APIENTRY glGetUniformLocation (GLuint program, const char* name);
+GL_APICALL int          GL_APIENTRY glGetUniformLocation (GLuint program, const GLchar* name);
 GL_APICALL void         GL_APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat* params);
 GL_APICALL void         GL_APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint* params);
-GL_APICALL void         GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void** pointer);
+GL_APICALL void         GL_APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid** pointer);
 GL_APICALL void         GL_APIENTRY glHint (GLenum target, GLenum mode);
 GL_APICALL GLboolean    GL_APIENTRY glIsBuffer (GLuint buffer);
 GL_APICALL GLboolean    GL_APIENTRY glIsEnabled (GLenum cap);
@@ -562,25 +563,25 @@
 GL_APICALL void         GL_APIENTRY glLinkProgram (GLuint program);
 GL_APICALL void         GL_APIENTRY glPixelStorei (GLenum pname, GLint param);
 GL_APICALL void         GL_APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);
-GL_APICALL void         GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels);
+GL_APICALL void         GL_APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels);
 GL_APICALL void         GL_APIENTRY glReleaseShaderCompiler (void);
 GL_APICALL void         GL_APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
 GL_APICALL void         GL_APIENTRY glSampleCoverage (GLclampf value, GLboolean invert);
 GL_APICALL void         GL_APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
-GL_APICALL void         GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length);
-GL_APICALL void         GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const char** string, const GLint* length);
+GL_APICALL void         GL_APIENTRY glShaderBinary (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length);
+GL_APICALL void         GL_APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar** string, const GLint* length);
 GL_APICALL void         GL_APIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask);
 GL_APICALL void         GL_APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask);
 GL_APICALL void         GL_APIENTRY glStencilMask (GLuint mask);
 GL_APICALL void         GL_APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask);
 GL_APICALL void         GL_APIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass);
 GL_APICALL void         GL_APIENTRY glStencilOpSeparate (GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-GL_APICALL void         GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void         GL_APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
 GL_APICALL void         GL_APIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param);
 GL_APICALL void         GL_APIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat* params);
 GL_APICALL void         GL_APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
 GL_APICALL void         GL_APIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint* params);
-GL_APICALL void         GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels);
+GL_APICALL void         GL_APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels);
 GL_APICALL void         GL_APIENTRY glUniform1f (GLint location, GLfloat x);
 GL_APICALL void         GL_APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat* v);
 GL_APICALL void         GL_APIENTRY glUniform1i (GLint location, GLint x);
@@ -610,7 +611,7 @@
 GL_APICALL void         GL_APIENTRY glVertexAttrib3fv (GLuint indx, const GLfloat* values);
 GL_APICALL void         GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
 GL_APICALL void         GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
-GL_APICALL void         GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr);
+GL_APICALL void         GL_APIENTRY glVertexAttribPointer (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr);
 GL_APICALL void         GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
 
 #ifdef __cplusplus
diff --git a/opengl/include/GLES2/gl2ext.h b/opengl/include/GLES2/gl2ext.h
index 72f1ae7..de5d65a 100644
--- a/opengl/include/GLES2/gl2ext.h
+++ b/opengl/include/GLES2/gl2ext.h
@@ -1,7 +1,7 @@
 #ifndef __gl2ext_h_
 #define __gl2ext_h_
 
-/* $Revision: 8271 $ on $Date:: 2009-05-21 09:33:40 -0700 #$ */
+/* $Revision: 10969 $ on $Date:: 2010-04-09 02:27:15 -0700 #$ */
 
 #ifdef __cplusplus
 extern "C" {
@@ -57,6 +57,11 @@
 typedef void* GLeglImageOES;
 #endif
 
+/* GL_OES_element_index_uint */
+#ifndef GL_OES_element_index_uint
+#define GL_UNSIGNED_INT                                         0x1405
+#endif
+
 /* GL_OES_get_program_binary */
 #ifndef GL_OES_get_program_binary
 #define GL_PROGRAM_BINARY_LENGTH_OES                            0x8741
@@ -100,8 +105,8 @@
 #define GL_STENCIL_INDEX4_OES                                   0x8D47
 #endif
 
-/* GL_OES_texture3D */
-#ifndef GL_OES_texture3D
+/* GL_OES_texture_3D */
+#ifndef GL_OES_texture_3D
 #define GL_TEXTURE_WRAP_R_OES                                   0x8072
 #define GL_TEXTURE_3D_OES                                       0x806F
 #define GL_TEXTURE_BINDING_3D_OES                               0x806A
@@ -110,11 +115,28 @@
 #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES        0x8CD4
 #endif
 
+/* GL_OES_texture_float */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_texture_float_linear */
+/* No new tokens introduced by this extension. */
+
 /* GL_OES_texture_half_float */
 #ifndef GL_OES_texture_half_float
 #define GL_HALF_FLOAT_OES                                       0x8D61
 #endif
 
+/* GL_OES_texture_half_float_linear */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_texture_npot */
+/* No new tokens introduced by this extension. */
+
+/* GL_OES_vertex_array_object */
+#ifndef GL_OES_vertex_array_object
+#define GL_VERTEX_ARRAY_BINDING_OES                             0x85B5
+#endif
+
 /* GL_OES_vertex_half_float */
 /* GL_HALF_FLOAT_OES defined in GL_OES_texture_half_float already. */
 
@@ -124,6 +146,11 @@
 #define GL_INT_10_10_10_2_OES                                   0x8DF7
 #endif
 
+/* GL_OES_texture_external */
+#ifndef GL_TEXTURE_EXTERNAL_OES
+#define GL_TEXTURE_EXTERNAL_OES                                 0x8D65
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension tokens
  *------------------------------------------------------------------------*/
@@ -141,11 +168,6 @@
 #define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD                      0x87EE
 #endif
 
-/* GL_AMD_program_binary_Z400 */
-#ifndef GL_AMD_program_binary_Z400
-#define GL_Z400_BINARY_AMD                                      0x8740
-#endif
-
 /* GL_AMD_performance_monitor */
 #ifndef GL_AMD_performance_monitor
 #define GL_COUNTER_TYPE_AMD                                     0x8BC0
@@ -157,35 +179,78 @@
 #define GL_PERFMON_RESULT_AMD                                   0x8BC6
 #endif
 
+/* GL_AMD_program_binary_Z400 */
+#ifndef GL_AMD_program_binary_Z400
+#define GL_Z400_BINARY_AMD                                      0x8740
+#endif
+
 /*------------------------------------------------------------------------*
  * EXT extension tokens
  *------------------------------------------------------------------------*/
 
+/* GL_EXT_blend_minmax */
+#ifndef GL_EXT_blend_minmax
+#define GL_MIN_EXT                                              0x8007
+#define GL_MAX_EXT                                              0x8008
+#endif
+
+/* GL_EXT_discard_framebuffer */
+#ifndef GL_EXT_discard_framebuffer
+#define GL_COLOR_EXT                                            0x1800
+#define GL_DEPTH_EXT                                            0x1801
+#define GL_STENCIL_EXT                                          0x1802
+#endif
+
+/* GL_EXT_multi_draw_arrays */
+/* No new tokens introduced by this extension. */
+
+/* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_read_format_bgra
+#define GL_BGRA_EXT                                             0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT                       0x8365
+#define GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT                       0x8366
+#endif
+
 /* GL_EXT_texture_filter_anisotropic */
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_TEXTURE_MAX_ANISOTROPY_EXT                           0x84FE
 #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       0x84FF
 #endif
 
+/* GL_EXT_texture_format_BGRA8888 */
+#ifndef GL_EXT_texture_format_BGRA8888
+#define GL_BGRA_EXT                                             0x80E1
+#endif
+
 /* GL_EXT_texture_type_2_10_10_10_REV */
 #ifndef GL_EXT_texture_type_2_10_10_10_REV
 #define GL_UNSIGNED_INT_2_10_10_10_REV_EXT                      0x8368
 #endif
 
-/* GL_EXT_texture_format_BGRA8888 */
-#ifndef GL_EXT_texture_format_BGRA8888
-#define GL_BGRA                                                 0x80E1
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT                         0x83F0
+#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT                        0x83F1
 #endif
 
 /*------------------------------------------------------------------------*
  * IMG extension tokens
  *------------------------------------------------------------------------*/
 
+/* GL_IMG_program_binary */
+#ifndef GL_IMG_program_binary
+#define GL_SGX_PROGRAM_BINARY_IMG                               0x9130
+#endif
+
 /* GL_IMG_read_format */
 #ifndef GL_IMG_read_format
-#define GL_BGRA                                                 0x80E1
-#define GL_UNSIGNED_SHORT_4_4_4_4_REV                           0x8365
-#define GL_UNSIGNED_SHORT_1_5_5_5_REV                           0x8366
+#define GL_BGRA_IMG                                             0x80E1
+#define GL_UNSIGNED_SHORT_4_4_4_4_REV_IMG                       0x8365
+#endif
+
+/* GL_IMG_shader_binary */
+#ifndef GL_IMG_shader_binary
+#define GL_SGX_BINARY_IMG                                       0x8C0A
 #endif
 
 /* GL_IMG_texture_compression_pvrtc */
@@ -196,6 +261,14 @@
 #define GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG                     0x8C03
 #endif
 
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_RENDERBUFFER_SAMPLES_IMG                             0x9133
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG               0x9134
+#define GL_MAX_SAMPLES_IMG                                      0x9135
+#define GL_TEXTURE_SAMPLES_IMG                                  0x9136
+#endif
+
 /*------------------------------------------------------------------------*
  * NV extension tokens
  *------------------------------------------------------------------------*/
@@ -207,6 +280,24 @@
 #define GL_FENCE_CONDITION_NV                                   0x84F4
 #endif
 
+/* GL_NV_coverage_sample */
+#ifndef GL_NV_coverage_sample
+#define GL_COVERAGE_COMPONENT_NV                                0x8ED0
+#define GL_COVERAGE_COMPONENT4_NV                               0x8ED1
+#define GL_COVERAGE_ATTACHMENT_NV                               0x8ED2
+#define GL_COVERAGE_BUFFERS_NV                                  0x8ED3
+#define GL_COVERAGE_SAMPLES_NV                                  0x8ED4
+#define GL_COVERAGE_ALL_FRAGMENTS_NV                            0x8ED5
+#define GL_COVERAGE_EDGE_FRAGMENTS_NV                           0x8ED6
+#define GL_COVERAGE_AUTOMATIC_NV                                0x8ED7
+#define GL_COVERAGE_BUFFER_BIT_NV                               0x8000
+#endif
+
+/* GL_NV_depth_nonlinear */
+#ifndef GL_NV_depth_nonlinear
+#define GL_DEPTH_COMPONENT16_NONLINEAR_NV                       0x8E2C
+#endif
+
 /*------------------------------------------------------------------------*
  * QCOM extension tokens
  *------------------------------------------------------------------------*/
@@ -214,11 +305,70 @@
 /* GL_QCOM_driver_control */
 /* No new tokens introduced by this extension. */
 
+/* GL_QCOM_extended_get */
+#ifndef GL_QCOM_extended_get
+#define GL_TEXTURE_WIDTH_QCOM                                   0x8BD2
+#define GL_TEXTURE_HEIGHT_QCOM                                  0x8BD3
+#define GL_TEXTURE_DEPTH_QCOM                                   0x8BD4
+#define GL_TEXTURE_INTERNAL_FORMAT_QCOM                         0x8BD5
+#define GL_TEXTURE_FORMAT_QCOM                                  0x8BD6
+#define GL_TEXTURE_TYPE_QCOM                                    0x8BD7
+#define GL_TEXTURE_IMAGE_VALID_QCOM                             0x8BD8
+#define GL_TEXTURE_NUM_LEVELS_QCOM                              0x8BD9
+#define GL_TEXTURE_TARGET_QCOM                                  0x8BDA
+#define GL_TEXTURE_OBJECT_VALID_QCOM                            0x8BDB
+#define GL_STATE_RESTORE                                        0x8BDC
+#endif
+
+/* GL_QCOM_extended_get2 */
+/* No new tokens introduced by this extension. */
+
 /* GL_QCOM_perfmon_global_mode */
 #ifndef GL_QCOM_perfmon_global_mode
 #define GL_PERFMON_GLOBAL_MODE_QCOM                             0x8FA0
 #endif
 
+/* GL_QCOM_writeonly_rendering */
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_WRITEONLY_RENDERING_QCOM                             0x8823
+#endif
+
+/* GL_QCOM_tiled_rendering */
+#ifndef GL_QCOM_tiled_rendering
+#define GL_COLOR_BUFFER_BIT0_QCOM                               0x00000001
+#define GL_COLOR_BUFFER_BIT1_QCOM                               0x00000002
+#define GL_COLOR_BUFFER_BIT2_QCOM                               0x00000004
+#define GL_COLOR_BUFFER_BIT3_QCOM                               0x00000008
+#define GL_COLOR_BUFFER_BIT4_QCOM                               0x00000010
+#define GL_COLOR_BUFFER_BIT5_QCOM                               0x00000020
+#define GL_COLOR_BUFFER_BIT6_QCOM                               0x00000040
+#define GL_COLOR_BUFFER_BIT7_QCOM                               0x00000080
+#define GL_DEPTH_BUFFER_BIT0_QCOM                               0x00000100
+#define GL_DEPTH_BUFFER_BIT1_QCOM                               0x00000200
+#define GL_DEPTH_BUFFER_BIT2_QCOM                               0x00000400
+#define GL_DEPTH_BUFFER_BIT3_QCOM                               0x00000800
+#define GL_DEPTH_BUFFER_BIT4_QCOM                               0x00001000
+#define GL_DEPTH_BUFFER_BIT5_QCOM                               0x00002000
+#define GL_DEPTH_BUFFER_BIT6_QCOM                               0x00004000
+#define GL_DEPTH_BUFFER_BIT7_QCOM                               0x00008000
+#define GL_STENCIL_BUFFER_BIT0_QCOM                             0x00010000
+#define GL_STENCIL_BUFFER_BIT1_QCOM                             0x00020000
+#define GL_STENCIL_BUFFER_BIT2_QCOM                             0x00040000
+#define GL_STENCIL_BUFFER_BIT3_QCOM                             0x00080000
+#define GL_STENCIL_BUFFER_BIT4_QCOM                             0x00100000
+#define GL_STENCIL_BUFFER_BIT5_QCOM                             0x00200000
+#define GL_STENCIL_BUFFER_BIT6_QCOM                             0x00400000
+#define GL_STENCIL_BUFFER_BIT7_QCOM                             0x00800000
+#define GL_MULTISAMPLE_BUFFER_BIT0_QCOM                         0x01000000
+#define GL_MULTISAMPLE_BUFFER_BIT1_QCOM                         0x02000000
+#define GL_MULTISAMPLE_BUFFER_BIT2_QCOM                         0x04000000
+#define GL_MULTISAMPLE_BUFFER_BIT3_QCOM                         0x08000000
+#define GL_MULTISAMPLE_BUFFER_BIT4_QCOM                         0x10000000
+#define GL_MULTISAMPLE_BUFFER_BIT5_QCOM                         0x20000000
+#define GL_MULTISAMPLE_BUFFER_BIT6_QCOM                         0x40000000
+#define GL_MULTISAMPLE_BUFFER_BIT7_QCOM                         0x80000000
+#endif
+
 /*------------------------------------------------------------------------*
  * End of extension tokens, start of corresponding extension functions
  *------------------------------------------------------------------------*/
@@ -237,17 +387,6 @@
 #define GL_OES_compressed_paletted_texture 1
 #endif
 
-/* GL_OES_EGL_image */
-#ifndef GL_OES_EGL_image
-#define GL_OES_EGL_image 1
-#ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
-GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
-#endif
-typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
-typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
-#endif
-
 /* GL_OES_depth24 */
 #ifndef GL_OES_depth24
 #define GL_OES_depth24 1
@@ -263,6 +402,17 @@
 #define GL_OES_depth_texture 1
 #endif
 
+/* GL_OES_EGL_image */
+#ifndef GL_OES_EGL_image
+#define GL_OES_EGL_image 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glEGLImageTargetTexture2DOES (GLenum target, GLeglImageOES image);
+GL_APICALL void GL_APIENTRY glEGLImageTargetRenderbufferStorageOES (GLenum target, GLeglImageOES image);
+#endif
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETTEXTURE2DOESPROC) (GLenum target, GLeglImageOES image);
+typedef void (GL_APIENTRYP PFNGLEGLIMAGETARGETRENDERBUFFERSTORAGEOESPROC) (GLenum target, GLeglImageOES image);
+#endif
+
 /* GL_OES_element_index_uint */
 #ifndef GL_OES_element_index_uint
 #define GL_OES_element_index_uint 1
@@ -282,11 +432,11 @@
 #ifndef GL_OES_get_program_binary
 #define GL_OES_get_program_binary 1
 #ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
-GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+GL_APICALL void GL_APIENTRY glGetProgramBinaryOES (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+GL_APICALL void GL_APIENTRY glProgramBinaryOES (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
 #endif
-typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary);
-typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const void *binary, GLint length);
+typedef void (GL_APIENTRYP PFNGLGETPROGRAMBINARYOESPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary);
+typedef void (GL_APIENTRYP PFNGLPROGRAMBINARYOESPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length);
 #endif
 
 /* GL_OES_mapbuffer */
@@ -295,11 +445,11 @@
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void* GL_APIENTRY glMapBufferOES (GLenum target, GLenum access);
 GL_APICALL GLboolean GL_APIENTRY glUnmapBufferOES (GLenum target);
-GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, void** params);
+GL_APICALL void GL_APIENTRY glGetBufferPointervOES (GLenum target, GLenum pname, GLvoid** params);
 #endif
 typedef void* (GL_APIENTRYP PFNGLMAPBUFFEROESPROC) (GLenum target, GLenum access);
 typedef GLboolean (GL_APIENTRYP PFNGLUNMAPBUFFEROESPROC) (GLenum target);
-typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, void** params);
+typedef void (GL_APIENTRYP PFNGLGETBUFFERPOINTERVOESPROC) (GLenum target, GLenum pname, GLvoid** params);
 #endif
 
 /* GL_OES_packed_depth_stencil */
@@ -331,46 +481,61 @@
 #ifndef GL_OES_texture_3D
 #define GL_OES_texture_3D 1
 #ifdef GL_GLEXT_PROTOTYPES
-GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels);
-GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
+GL_APICALL void GL_APIENTRY glTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
+GL_APICALL void GL_APIENTRY glTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
 GL_APICALL void GL_APIENTRY glCopyTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data);
-GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data);
+GL_APICALL void GL_APIENTRY glCompressedTexImage3DOES (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+GL_APICALL void GL_APIENTRY glCompressedTexSubImage3DOES (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
 GL_APICALL void GL_APIENTRY glFramebufferTexture3DOES (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 #endif
 typedef void (GL_APIENTRYP PFNGLTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels);
-typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels);
+typedef void (GL_APIENTRYP PFNGLTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels);
 typedef void (GL_APIENTRYP PFNGLCOPYTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data);
-typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DOESPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data);
+typedef void (GL_APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DOESPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data);
 typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DOES) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset);
 #endif
 
-/* GL_OES_texture_float_linear */
-#ifndef GL_OES_texture_float_linear
-#define GL_OES_texture_float_linear 1
-#endif
-
-/* GL_OES_texture_half_float_linear */
-#ifndef GL_OES_texture_half_float_linear
-#define GL_OES_texture_half_float_linear 1
-#endif
-
 /* GL_OES_texture_float */
 #ifndef GL_OES_texture_float
 #define GL_OES_texture_float 1
 #endif
 
+/* GL_OES_texture_float_linear */
+#ifndef GL_OES_texture_float_linear
+#define GL_OES_texture_float_linear 1
+#endif
+
 /* GL_OES_texture_half_float */
 #ifndef GL_OES_texture_half_float
 #define GL_OES_texture_half_float 1
 #endif
 
+/* GL_OES_texture_half_float_linear */
+#ifndef GL_OES_texture_half_float_linear
+#define GL_OES_texture_half_float_linear 1
+#endif
+
 /* GL_OES_texture_npot */
 #ifndef GL_OES_texture_npot
 #define GL_OES_texture_npot 1
 #endif
 
+/* GL_OES_vertex_array_object */
+#ifndef GL_OES_vertex_array_object
+#define GL_OES_vertex_array_object 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glBindVertexArrayOES (GLuint array);
+GL_APICALL void GL_APIENTRY glDeleteVertexArraysOES (GLsizei n, const GLuint *arrays);
+GL_APICALL void GL_APIENTRY glGenVertexArraysOES (GLsizei n, GLuint *arrays);
+GL_APICALL GLboolean GL_APIENTRY glIsVertexArrayOES (GLuint array);
+#endif
+typedef void (GL_APIENTRYP PFNGLBINDVERTEXARRAYOESPROC) (GLuint array);
+typedef void (GL_APIENTRYP PFNGLDELETEVERTEXARRAYSOESPROC) (GLsizei n, const GLuint *arrays);
+typedef void (GL_APIENTRYP PFNGLGENVERTEXARRAYSOESPROC) (GLsizei n, GLuint *arrays);
+typedef GLboolean (GL_APIENTRYP PFNGLISVERTEXARRAYOESPROC) (GLuint array);
+#endif
+
 /* GL_OES_vertex_half_float */
 #ifndef GL_OES_vertex_half_float
 #define GL_OES_vertex_half_float 1
@@ -381,6 +546,11 @@
 #define GL_OES_vertex_type_10_10_10_2 1
 #endif
 
+/* GL_OES_texture_external */
+#ifndef GL_OES_texture_external
+#define GL_OES_texture_external 1
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension functions
  *------------------------------------------------------------------------*/
@@ -395,20 +565,15 @@
 #define GL_AMD_compressed_ATC_texture 1
 #endif
 
-/* GL_AMD_program_binary_Z400 */
-#ifndef GL_AMD_program_binary_Z400
-#define GL_AMD_program_binary_Z400 1
-#endif
-
 /* AMD_performance_monitor */
 #ifndef GL_AMD_performance_monitor
 #define GL_AMD_performance_monitor 1
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
 GL_APICALL void GL_APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
-GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, char *groupString);
-GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString);
-GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, void *data);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+GL_APICALL void GL_APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
 GL_APICALL void GL_APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors);
 GL_APICALL void GL_APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors);
 GL_APICALL void GL_APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
@@ -418,9 +583,9 @@
 #endif
 typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups);
 typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters);
-typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, char *groupString);
-typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString);
-typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString);
+typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data);
 typedef void (GL_APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
 typedef void (GL_APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors);
 typedef void (GL_APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList);
@@ -429,39 +594,99 @@
 typedef void (GL_APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten);
 #endif
 
+/* GL_AMD_program_binary_Z400 */
+#ifndef GL_AMD_program_binary_Z400
+#define GL_AMD_program_binary_Z400 1
+#endif
+
 /*------------------------------------------------------------------------*
  * EXT extension functions
  *------------------------------------------------------------------------*/
 
+/* GL_EXT_blend_minmax */
+#ifndef GL_EXT_blend_minmax
+#define GL_EXT_blend_minmax 1
+#endif
+
+/* GL_EXT_discard_framebuffer */
+#ifndef GL_EXT_discard_framebuffer
+#define GL_EXT_discard_framebuffer 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+typedef void (GL_APIENTRYP PFNGLDISCARDFRAMEBUFFEREXTPROC) (GLenum target, GLsizei numAttachments, const GLenum *attachments);
+#endif
+
+#ifndef GL_EXT_multi_draw_arrays
+#define GL_EXT_multi_draw_arrays 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glMultiDrawArraysEXT (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+GL_APICALL void GL_APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount);
+typedef void (GL_APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount);
+#endif
+
+/* GL_EXT_read_format_bgra */
+#ifndef GL_EXT_read_format_bgra
+#define GL_EXT_read_format_bgra 1
+#endif
+
 /* GL_EXT_texture_filter_anisotropic */
 #ifndef GL_EXT_texture_filter_anisotropic
 #define GL_EXT_texture_filter_anisotropic 1
 #endif
 
-/* GL_EXT_texture_type_2_10_10_10_REV */
-#ifndef GL_EXT_texture_type_2_10_10_10_REV
-#define GL_EXT_texture_type_2_10_10_10_REV 1
-#endif
-
 /* GL_EXT_texture_format_BGRA8888 */
 #ifndef GL_EXT_texture_format_BGRA8888
 #define GL_EXT_texture_format_BGRA8888 1
 #endif
 
+/* GL_EXT_texture_type_2_10_10_10_REV */
+#ifndef GL_EXT_texture_type_2_10_10_10_REV
+#define GL_EXT_texture_type_2_10_10_10_REV 1
+#endif
+
+/* GL_EXT_texture_compression_dxt1 */
+#ifndef GL_EXT_texture_compression_dxt1
+#define GL_EXT_texture_compression_dxt1 1
+#endif
+
 /*------------------------------------------------------------------------*
  * IMG extension functions
  *------------------------------------------------------------------------*/
 
+/* GL_IMG_program_binary */
+#ifndef GL_IMG_program_binary
+#define GL_IMG_program_binary 1
+#endif
+
 /* GL_IMG_read_format */
 #ifndef GL_IMG_read_format
 #define GL_IMG_read_format 1
 #endif
 
+/* GL_IMG_shader_binary */
+#ifndef GL_IMG_shader_binary
+#define GL_IMG_shader_binary 1
+#endif
+
 /* GL_IMG_texture_compression_pvrtc */
 #ifndef GL_IMG_texture_compression_pvrtc
 #define GL_IMG_texture_compression_pvrtc 1
 #endif
 
+/* GL_IMG_multisampled_render_to_texture */
+#ifndef GL_IMG_multisampled_render_to_texture
+#define GL_IMG_multisampled_render_to_texture 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleIMG (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glFramebufferTexture2DMultisampleIMG (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEIMG) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+typedef void (GL_APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEIMG) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples);
+#endif
+
 /*------------------------------------------------------------------------*
  * NV extension functions
  *------------------------------------------------------------------------*/
@@ -487,6 +712,22 @@
 typedef void (GL_APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition);
 #endif
 
+/* GL_NV_coverage_sample */
+#ifndef GL_NV_coverage_sample
+#define GL_NV_coverage_sample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glCoverageMaskNV (GLboolean mask);
+GL_APICALL void GL_APIENTRY glCoverageOperationNV (GLenum operation);
+#endif
+typedef void (GL_APIENTRYP PFNGLCOVERAGEMASKNVPROC) (GLboolean mask);
+typedef void (GL_APIENTRYP PFNGLCOVERAGEOPERATIONNVPROC) (GLenum operation);
+#endif
+
+/* GL_NV_depth_nonlinear */
+#ifndef GL_NV_depth_nonlinear
+#define GL_NV_depth_nonlinear 1
+#endif
+
 /*------------------------------------------------------------------------*
  * QCOM extension functions
  *------------------------------------------------------------------------*/
@@ -496,21 +737,75 @@
 #define GL_QCOM_driver_control 1
 #ifdef GL_GLEXT_PROTOTYPES
 GL_APICALL void GL_APIENTRY glGetDriverControlsQCOM (GLint *num, GLsizei size, GLuint *driverControls);
-GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString);
+GL_APICALL void GL_APIENTRY glGetDriverControlStringQCOM (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
 GL_APICALL void GL_APIENTRY glEnableDriverControlQCOM (GLuint driverControl);
 GL_APICALL void GL_APIENTRY glDisableDriverControlQCOM (GLuint driverControl);
 #endif
 typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSQCOMPROC) (GLint *num, GLsizei size, GLuint *driverControls);
-typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString);
+typedef void (GL_APIENTRYP PFNGLGETDRIVERCONTROLSTRINGQCOMPROC) (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString);
 typedef void (GL_APIENTRYP PFNGLENABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
 typedef void (GL_APIENTRYP PFNGLDISABLEDRIVERCONTROLQCOMPROC) (GLuint driverControl);
 #endif
 
+/* GL_QCOM_extended_get */
+#ifndef GL_QCOM_extended_get
+#define GL_QCOM_extended_get 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetTexturesQCOM (GLuint *textures, GLint maxTextures, GLint *numTextures);
+GL_APICALL void GL_APIENTRY glExtGetBuffersQCOM (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+GL_APICALL void GL_APIENTRY glExtGetRenderbuffersQCOM (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+GL_APICALL void GL_APIENTRY glExtGetFramebuffersQCOM (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+GL_APICALL void GL_APIENTRY glExtGetTexLevelParameterivQCOM (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+GL_APICALL void GL_APIENTRY glExtTexObjectStateOverrideiQCOM (GLenum target, GLenum pname, GLint param);
+GL_APICALL void GL_APIENTRY glExtGetTexSubImageQCOM (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+GL_APICALL void GL_APIENTRY glExtGetBufferPointervQCOM (GLenum target, GLvoid **params);
+#endif
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXTURESQCOMPROC) (GLuint *textures, GLint maxTextures, GLint *numTextures);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERSQCOMPROC) (GLuint *buffers, GLint maxBuffers, GLint *numBuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETRENDERBUFFERSQCOMPROC) (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETFRAMEBUFFERSQCOMPROC) (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXLEVELPARAMETERIVQCOMPROC) (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params);
+typedef void (GL_APIENTRYP PFNGLEXTTEXOBJECTSTATEOVERRIDEIQCOMPROC) (GLenum target, GLenum pname, GLint param);
+typedef void (GL_APIENTRYP PFNGLEXTGETTEXSUBIMAGEQCOMPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels);
+typedef void (GL_APIENTRYP PFNGLEXTGETBUFFERPOINTERVQCOMPROC) (GLenum target, GLvoid **params);
+#endif
+
+/* GL_QCOM_extended_get2 */
+#ifndef GL_QCOM_extended_get2
+#define GL_QCOM_extended_get2 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glExtGetShadersQCOM (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+GL_APICALL void GL_APIENTRY glExtGetProgramsQCOM (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+GL_APICALL GLboolean GL_APIENTRY glExtIsProgramBinaryQCOM (GLuint program);
+GL_APICALL void GL_APIENTRY glExtGetProgramBinarySourceQCOM (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+typedef void (GL_APIENTRYP PFNGLEXTGETSHADERSQCOMPROC) (GLuint *shaders, GLint maxShaders, GLint *numShaders);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMSQCOMPROC) (GLuint *programs, GLint maxPrograms, GLint *numPrograms);
+typedef GLboolean (GL_APIENTRYP PFNGLEXTISPROGRAMBINARYQCOMPROC) (GLuint program);
+typedef void (GL_APIENTRYP PFNGLEXTGETPROGRAMBINARYSOURCEQCOMPROC) (GLuint program, GLenum shadertype, GLchar *source, GLint *length);
+#endif
+
 /* GL_QCOM_perfmon_global_mode */
 #ifndef GL_QCOM_perfmon_global_mode
 #define GL_QCOM_perfmon_global_mode 1
 #endif
 
+/* GL_QCOM_writeonly_rendering */
+#ifndef GL_QCOM_writeonly_rendering
+#define GL_QCOM_writeonly_rendering 1
+#endif
+
+/* GL_QCOM_tiled_rendering */
+#ifndef GL_QCOM_tiled_rendering
+#define GL_QCOM_tiled_rendering 1
+#ifdef GL_GLEXT_PROTOTYPES
+GL_APICALL void GL_APIENTRY glStartTilingQCOM (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+GL_APICALL void GL_APIENTRY glEndTilingQCOM (GLbitfield preserveMask);
+#endif
+typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask);
+typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/opengl/include/GLES2/gl2platform.h b/opengl/include/GLES2/gl2platform.h
index 3e9036c..c9fa3c4 100644
--- a/opengl/include/GLES2/gl2platform.h
+++ b/opengl/include/GLES2/gl2platform.h
@@ -1,7 +1,7 @@
 #ifndef __gl2platform_h_
 #define __gl2platform_h_
 
-/* $Revision: 7173 $ on $Date:: 2009-01-09 11:18:21 -0800 #$ */
+/* $Revision: 10602 $ on $Date:: 2010-03-04 22:35:34 -0800 #$ */
 
 /*
  * This document is licensed under the SGI Free Software B License Version
@@ -9,7 +9,6 @@
  */
 
 /* Platform-specific types and definitions for OpenGL ES 2.X  gl2.h
- * Last modified on 2008/12/19
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
@@ -24,6 +23,8 @@
 #define GL_APICALL  KHRONOS_APICALL
 #endif
 
+#ifndef GL_APIENTRY
 #define GL_APIENTRY KHRONOS_APIENTRY
+#endif
 
 #endif /* __gl2platform_h_ */
diff --git a/opengl/libagl/Android.mk b/opengl/libagl/Android.mk
index 8abd649..b5c018f 100644
--- a/opengl/libagl/Android.mk
+++ b/opengl/libagl/Android.mk
@@ -6,9 +6,6 @@
 
 include $(CLEAR_VARS)
 
-# Set to 1 to use gralloc and copybits
-LIBAGL_USE_GRALLOC_COPYBITS := 1
-
 LOCAL_SRC_FILES:= \
 	egl.cpp                     \
 	state.cpp		            \
@@ -51,13 +48,6 @@
     LOCAL_C_INCLUDES += bionic/libc/private
 endif
 
-ifeq ($(LIBAGL_USE_GRALLOC_COPYBITS),1)
-    LOCAL_CFLAGS += -DLIBAGL_USE_GRALLOC_COPYBITS
-    LOCAL_SRC_FILES += copybit.cpp
-    LOCAL_SHARED_LIBRARIES += libui
-endif
-
-
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
 LOCAL_MODULE:= libGLES_android
 
diff --git a/opengl/libagl/TextureObjectManager.cpp b/opengl/libagl/TextureObjectManager.cpp
index 255ccac..bbb82fc 100644
--- a/opengl/libagl/TextureObjectManager.cpp
+++ b/opengl/libagl/TextureObjectManager.cpp
@@ -55,9 +55,6 @@
     memset(crop_rect, 0, sizeof(crop_rect));
     generate_mipmap = GL_FALSE;
     direct = GL_FALSE;
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    try_copybit = false;
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
     buffer = 0;
 }
 
diff --git a/opengl/libagl/TextureObjectManager.h b/opengl/libagl/TextureObjectManager.h
index 279e040..70e3bef 100644
--- a/opengl/libagl/TextureObjectManager.h
+++ b/opengl/libagl/TextureObjectManager.h
@@ -80,9 +80,6 @@
     GLint               crop_rect[4];
     GLint               generate_mipmap;
     GLint               direct;
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    bool                try_copybit;
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
     android_native_buffer_t* buffer;
 };
 
diff --git a/opengl/libagl/array.cpp b/opengl/libagl/array.cpp
index 71825c5..7fbe9b5 100644
--- a/opengl/libagl/array.cpp
+++ b/opengl/libagl/array.cpp
@@ -26,9 +26,6 @@
 #include "primitives.h"
 #include "texture.h"
 #include "BufferObjectManager.h"
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include "copybit.h"
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 
 // ----------------------------------------------------------------------------
 
@@ -688,8 +685,8 @@
             } while (num);
         }
         if (count) {
-            v0 = c->vc.vBuffer + 2 + num - 2;
-            v1 = c->vc.vBuffer + 2 + num - 1;
+            v0 = c->vc.vBuffer + 2 + vcs - 2;
+            v1 = c->vc.vBuffer + 2 + vcs - 1;
             if ((winding&2) == 0) {
                 // for strips copy back the two last compiled vertices
                 c->vc.vBuffer[0] = *v0;
@@ -707,12 +704,6 @@
 
 void drawPrimitivesTriangleFan(ogles_context_t* c,
         GLint first, GLsizei count) {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (drawTriangleFanWithCopybit(c, first, count)) {
-        return;
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     drawPrimitivesTriangleFanOrStrip(c, first, count, 2);
 }
 
diff --git a/opengl/libagl/copybit.cpp b/opengl/libagl/copybit.cpp
deleted file mode 100644
index 67d1ce7..0000000
--- a/opengl/libagl/copybit.cpp
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
-**
-** Copyright 2009, 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.
-*/
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "context.h"
-#include "fp.h"
-#include "state.h"
-#include "matrix.h"
-#include "vertex.h"
-#include "light.h"
-#include "primitives.h"
-#include "texture.h"
-#include "BufferObjectManager.h"
-#include "TextureObjectManager.h"
-
-#include <hardware/gralloc.h>
-#include <hardware/copybit.h>
-#include <private/ui/android_natives_priv.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/Region.h>
-#include <ui/Rect.h>
-
-
-#define DEBUG_COPYBIT false
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-static void textureToCopyBitImage(
-        const GGLSurface* surface, int32_t opFormat, 
-        android_native_buffer_t* buffer, copybit_image_t* img)
-{
-    img->w      = surface->stride;
-    img->h      = surface->height;
-    img->format = opFormat;
-    img->base   = surface->data;
-    img->handle = (native_handle_t *)buffer->handle;
-}
-
-struct clipRectRegion : public copybit_region_t {
-    clipRectRegion(ogles_context_t* c) 
-    {
-        scissor_t const* scissor = &c->rasterizer.state.scissor;
-        r.l = scissor->left;
-        r.t = scissor->top;
-        r.r = scissor->right;
-        r.b = scissor->bottom;
-        next = iterate; 
-    }
-private:
-    static int iterate(copybit_region_t const * self, copybit_rect_t* rect) {
-        *rect = static_cast<clipRectRegion const*>(self)->r;
-        const_cast<copybit_region_t *>(self)->next = iterate_done;
-        return 1;
-    }
-    static int iterate_done(copybit_region_t const *, copybit_rect_t*) {
-        return 0;
-    }
-public:
-    copybit_rect_t r;
-};
-
-static bool supportedCopybitsFormat(int format) {
-    switch (format) {
-    case COPYBIT_FORMAT_RGBA_8888:
-    case COPYBIT_FORMAT_RGBX_8888:
-    case COPYBIT_FORMAT_RGB_888:
-    case COPYBIT_FORMAT_RGB_565:
-    case COPYBIT_FORMAT_BGRA_8888:
-    case COPYBIT_FORMAT_RGBA_5551:
-    case COPYBIT_FORMAT_RGBA_4444:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static bool hasAlpha(int format) {
-    switch (format) {
-    case COPYBIT_FORMAT_RGBA_8888:
-    case COPYBIT_FORMAT_BGRA_8888:
-    case COPYBIT_FORMAT_RGBA_5551:
-    case COPYBIT_FORMAT_RGBA_4444:
-        return true;
-    default:
-        return false;
-    }
-}
-
-static inline int fixedToByte(GGLfixed val) {
-    return (val - (val >> 8)) >> 8;
-}
-
-/**
- * Performs a quick check of the rendering state. If this function returns
- * false we cannot use the copybit driver.
- */
-
-static bool checkContext(ogles_context_t* c) {
-
-	// By convention copybitQuickCheckContext() has already returned true.
-	// avoid checking the same information again.
-	
-    if (c->copybits.blitEngine == NULL) {
-        LOGD_IF(DEBUG_COPYBIT, "no copybit hal");
-        return false;
-    }
-
-    if (c->rasterizer.state.enables
-                    & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_FOG)) {
-        LOGD_IF(DEBUG_COPYBIT, "depth test and/or fog");
-        return false;
-    }
-
-    // Note: The drawSurfaceBuffer is only set for destination
-    // surfaces types that are supported by the hardware and
-    // do not have an alpha channel. So we don't have to re-check that here.
-
-    static const int tmu = 0;
-    texture_unit_t& u(c->textures.tmu[tmu]);
-    EGLTextureObject* textureObject = u.texture;
-
-    if (!supportedCopybitsFormat(textureObject->surface.format)) {
-        LOGD_IF(DEBUG_COPYBIT, "texture format not supported");
-        return false;
-    }
-    return true;
-}
-
-
-static bool copybit(GLint x, GLint y,
-        GLint w, GLint h,
-        EGLTextureObject* textureObject,
-        const GLint* crop_rect,
-        int transform,
-        ogles_context_t* c)
-{
-    status_t err = NO_ERROR;
-
-    // We assume checkContext has already been called and has already
-    // returned true.
-
-    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
-
-    y = cbSurface.height - (y + h);
-
-    const GLint Ucr = crop_rect[0];
-    const GLint Vcr = crop_rect[1];
-    const GLint Wcr = crop_rect[2];
-    const GLint Hcr = crop_rect[3];
-
-    GLint screen_w = w;
-    GLint screen_h = h;
-    int32_t dsdx = Wcr << 16;   // dsdx =  ((Wcr/screen_w)/Wt)*Wt
-    int32_t dtdy = Hcr << 16;   // dtdy = -((Hcr/screen_h)/Ht)*Ht
-    if (transform & COPYBIT_TRANSFORM_ROT_90) {
-        swap(screen_w, screen_h);
-    }
-    if (dsdx!=screen_w || dtdy!=screen_h) {
-        // in most cases the divide is not needed
-        dsdx /= screen_w;
-        dtdy /= screen_h;
-    }
-    dtdy = -dtdy; // see equation of dtdy above
-
-    // copybit doesn't say anything about filtering, so we can't
-    // discriminate. On msm7k, copybit will always filter.
-    // the code below handles min/mag filters, we keep it as a reference.
-    
-#ifdef MIN_MAG_FILTER
-    int32_t texelArea = gglMulx(dtdy, dsdx);
-    if (texelArea < FIXED_ONE && textureObject->mag_filter != GL_LINEAR) {
-        // Non-linear filtering on a texture enlargement.
-        LOGD_IF(DEBUG_COPYBIT, "mag filter is not GL_LINEAR");
-        return false;
-    }
-    if (texelArea > FIXED_ONE && textureObject->min_filter != GL_LINEAR) {
-        // Non-linear filtering on an texture shrink.
-        LOGD_IF(DEBUG_COPYBIT, "min filter is not GL_LINEAR");
-        return false;
-    }
-#endif
-    
-    const uint32_t enables = c->rasterizer.state.enables;
-    int planeAlpha = 255;
-    bool alphaPlaneWorkaround = false;
-    static const int tmu = 0;
-    texture_t& tev(c->rasterizer.state.texture[tmu]);
-    int32_t opFormat = textureObject->surface.format;
-    const bool srcTextureHasAlpha = hasAlpha(opFormat);
-    if (!srcTextureHasAlpha) {
-        planeAlpha = fixedToByte(c->currentColorClamped.a);
-    }
-
-    const bool cbHasAlpha = hasAlpha(cbSurface.format);
-    bool blending = false;
-    if ((enables & GGL_ENABLE_BLENDING)
-            && !(c->rasterizer.state.blend.src == GL_ONE
-                    && c->rasterizer.state.blend.dst == GL_ZERO)) {
-        // Blending is OK if it is
-        // the exact kind of blending that the copybits hardware supports.
-        // Note: The hardware only supports
-        // GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA,
-        // But the surface flinger uses GL_ONE / GL_ONE_MINUS_SRC_ALPHA.
-        // We substitute GL_SRC_ALPHA / GL_ONE_MINUS_SRC_ALPHA in that case,
-        // because the performance is worth it, even if the results are
-        // not correct.
-        if (!((c->rasterizer.state.blend.src == GL_SRC_ALPHA
-                || c->rasterizer.state.blend.src == GL_ONE)
-                && c->rasterizer.state.blend.dst == GL_ONE_MINUS_SRC_ALPHA
-                && c->rasterizer.state.blend.alpha_separate == 0)) {
-            // Incompatible blend mode.
-            LOGD_IF(DEBUG_COPYBIT, "incompatible blend mode");
-            return false;
-        }
-        blending = true;
-    } else {
-        if (cbHasAlpha) {
-            // NOTE: the result will be slightly wrong in this case because
-            // the destination alpha channel will be set to 1.0 instead of
-            // the iterated alpha value. *shrug*.
-        }
-        // disable plane blending and src blending for supported formats
-        planeAlpha = 255;
-        if (opFormat == COPYBIT_FORMAT_RGBA_8888) {
-            opFormat = COPYBIT_FORMAT_RGBX_8888;
-        } else {
-            if (srcTextureHasAlpha) {
-                LOGD_IF(DEBUG_COPYBIT, "texture format requires blending");
-                return false;
-            }
-        }
-    }
-
-    switch (tev.env) {
-    case GGL_REPLACE:
-        break;
-    case GGL_MODULATE:
-        // only cases allowed is:
-        // RGB  source, color={1,1,1,a} -> can be done with GL_REPLACE
-        // RGBA source, color={1,1,1,1} -> can be done with GL_REPLACE
-        if (blending) {
-            if (c->currentColorClamped.r == c->currentColorClamped.a &&
-                c->currentColorClamped.g == c->currentColorClamped.a &&
-                c->currentColorClamped.b == c->currentColorClamped.a) {
-                // TODO: RGBA source, color={1,1,1,a} / regular-blending
-                // is equivalent
-                alphaPlaneWorkaround = true;
-                break;
-            }
-        }
-        LOGD_IF(DEBUG_COPYBIT, "GGL_MODULATE");
-        return false;
-    default:
-        // Incompatible texture environment.
-        LOGD_IF(DEBUG_COPYBIT, "incompatible texture environment");
-        return false;
-    }
-
-    copybit_device_t* copybit = c->copybits.blitEngine;
-    copybit_image_t src;
-    textureToCopyBitImage(&textureObject->surface, opFormat,
-            textureObject->buffer, &src);
-    copybit_rect_t srect = { Ucr, Vcr + Hcr, Ucr + Wcr, Vcr };
-
-    /*
-     *  Below we perform extra passes needed to emulate things the h/w
-     * cannot do.
-     */
-
-    const GLfixed minScaleInv = gglDivQ(0x10000, c->copybits.minScale, 16);
-    const GLfixed maxScaleInv = gglDivQ(0x10000, c->copybits.maxScale, 16);
-
-    sp<GraphicBuffer> tempBitmap;
-
-    if (dsdx < maxScaleInv || dsdx > minScaleInv ||
-        dtdy < maxScaleInv || dtdy > minScaleInv)
-    {
-        // The requested scale is out of the range the hardware
-        // can support.
-        LOGD_IF(DEBUG_COPYBIT,
-                "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
-                dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-
-        int32_t xscale=0x10000, yscale=0x10000;
-        if (dsdx > minScaleInv)         xscale = c->copybits.minScale;
-        else if (dsdx < maxScaleInv)    xscale = c->copybits.maxScale;
-        if (dtdy > minScaleInv)         yscale = c->copybits.minScale;
-        else if (dtdy < maxScaleInv)    yscale = c->copybits.maxScale;
-        dsdx = gglMulx(dsdx, xscale);
-        dtdy = gglMulx(dtdy, yscale);
-
-        /* we handle only one step of resizing below. Handling an arbitrary
-         * number is relatively easy (replace "if" above by "while"), but requires
-         * two intermediate buffers and so far we never had the need.
-         */
-
-        if (dsdx < maxScaleInv || dsdx > minScaleInv ||
-            dtdy < maxScaleInv || dtdy > minScaleInv) {
-            LOGD_IF(DEBUG_COPYBIT,
-                    "scale out of range dsdx=%08x (Wcr=%d / w=%d), "
-                    "dtdy=%08x (Hcr=%d / h=%d), Ucr=%d, Vcr=%d",
-                    dsdx, Wcr, w, dtdy, Hcr, h, Ucr, Vcr);
-            return false;
-        }
-
-        const int tmp_w = gglMulx(srect.r - srect.l, xscale, 16);
-        const int tmp_h = gglMulx(srect.b - srect.t, yscale, 16);
-
-        LOGD_IF(DEBUG_COPYBIT,
-                "xscale=%08x, yscale=%08x, dsdx=%08x, dtdy=%08x, tmp_w=%d, tmp_h=%d",
-                xscale, yscale, dsdx, dtdy, tmp_w, tmp_h);
-
-        tempBitmap = new GraphicBuffer(
-                    tmp_w, tmp_h, src.format,
-                    GraphicBuffer::USAGE_HW_2D);
-
-        err = tempBitmap->initCheck();
-        if (err == NO_ERROR) {
-            copybit_image_t tmp_dst;
-            copybit_rect_t tmp_rect;
-            tmp_dst.w = tmp_w;
-            tmp_dst.h = tmp_h;
-            tmp_dst.format = tempBitmap->format;
-            tmp_dst.handle = (native_handle_t*)tempBitmap->getNativeBuffer()->handle;
-            tmp_rect.l = 0;
-            tmp_rect.t = 0;
-            tmp_rect.r = tmp_dst.w;
-            tmp_rect.b = tmp_dst.h;
-            region_iterator tmp_it(Region(Rect(tmp_rect.r, tmp_rect.b)));
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-            err = copybit->stretch(copybit,
-                    &tmp_dst, &src, &tmp_rect, &srect, &tmp_it);
-            src = tmp_dst;
-            srect = tmp_rect;
-        }
-    }
-
-    copybit_image_t dst;
-    textureToCopyBitImage(&cbSurface, cbSurface.format,
-            c->copybits.drawSurfaceBuffer, &dst);
-    copybit_rect_t drect = {x, y, x+w, y+h};
-
-
-    /* and now the alpha-plane hack. This handles the "Fade" case of a
-     * texture with an alpha channel.
-     */
-    if (alphaPlaneWorkaround) {
-        sp<GraphicBuffer> tempCb = new GraphicBuffer(
-                    w, h, COPYBIT_FORMAT_RGB_565,
-                    GraphicBuffer::USAGE_HW_2D);
-
-        err = tempCb->initCheck();
-
-        copybit_image_t tmpCbImg;
-        copybit_rect_t tmpCbRect;
-        copybit_rect_t tmpdrect = drect;
-        tmpCbImg.w = w;
-        tmpCbImg.h = h;
-        tmpCbImg.format = tempCb->format;
-        tmpCbImg.handle = (native_handle_t*)tempCb->getNativeBuffer()->handle;
-        tmpCbRect.l = 0;
-        tmpCbRect.t = 0;
-
-        if (drect.l < 0) {
-            tmpCbRect.l = -tmpdrect.l;
-            tmpdrect.l = 0;
-        }
-        if (drect.t < 0) {
-            tmpCbRect.t = -tmpdrect.t;
-            tmpdrect.t = 0;
-        }
-        if (drect.l + tmpCbImg.w > dst.w) {
-            tmpCbImg.w = dst.w - drect.l;
-            tmpdrect.r = dst.w;
-        }
-        if (drect.t + tmpCbImg.h > dst.h) {
-            tmpCbImg.h = dst.h - drect.t;
-            tmpdrect.b = dst.h;
-        }
-
-        tmpCbRect.r = tmpCbImg.w;
-        tmpCbRect.b = tmpCbImg.h;
-
-        if (!err) {
-            // first make a copy of the destination buffer
-            region_iterator tmp_it(Region(Rect(w, h)));
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_DISABLE);
-            err = copybit->stretch(copybit,
-                    &tmpCbImg, &dst, &tmpCbRect, &tmpdrect, &tmp_it);
-        }
-        if (!err) {
-            // then proceed as usual, but without the alpha plane
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-            copybit->set_parameter(copybit, COPYBIT_DITHER,
-                    (enables & GGL_ENABLE_DITHER) ?
-                            COPYBIT_ENABLE : COPYBIT_DISABLE);
-            clipRectRegion it(c);
-            err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-        }
-        if (!err) {
-            // finally copy back the destination on top with 1-alphaplane
-            int invPlaneAlpha = 0xFF - fixedToByte(c->currentColorClamped.a);
-            clipRectRegion it(c);
-            copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, invPlaneAlpha);
-            copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-            err = copybit->stretch(copybit,
-                    &dst, &tmpCbImg, &tmpdrect, &tmpCbRect, &it);
-        }
-    } else {
-        copybit->set_parameter(copybit, COPYBIT_TRANSFORM, transform);
-        copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, planeAlpha);
-        copybit->set_parameter(copybit, COPYBIT_DITHER,
-                (enables & GGL_ENABLE_DITHER) ?
-                        COPYBIT_ENABLE : COPYBIT_DISABLE);
-        clipRectRegion it(c);
-
-        LOGD_IF(0,
-             "dst={%d, %d, %d, %p, %p}, "
-             "src={%d, %d, %d, %p, %p}, "
-             "drect={%d,%d,%d,%d}, "
-             "srect={%d,%d,%d,%d}, "
-             "it={%d,%d,%d,%d}, " ,
-             dst.w, dst.h, dst.format, dst.base, dst.handle,
-             src.w, src.h, src.format, src.base, src.handle,
-             drect.l, drect.t, drect.r, drect.b,
-             srect.l, srect.t, srect.r, srect.b,
-             it.r.l, it.r.t, it.r.r, it.r.b
-        );
-
-        err = copybit->stretch(copybit, &dst, &src, &drect, &srect, &it);
-    }
-    if (err != NO_ERROR) {
-        c->textures.tmu[0].texture->try_copybit = false;
-    }
-    return err == NO_ERROR ? true : false;
-}
-
-/*
- * Try to draw a triangle fan with copybit, return false if we fail.
- */
-bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first, GLsizei count)
-{
-    if (!checkContext(c)) {
-        return false;
-    }
-
-    // FIXME: we should handle culling  here
-    c->arrays.compileElements(c, c->vc.vBuffer, 0, 4);
-
-    // we detect if we're dealing with a rectangle, by comparing the
-    // rectangles {v0,v2} and {v1,v3} which should be identical.
-    
-    // NOTE: we should check that the rectangle is window aligned, however
-    // if we do that, the optimization won't be taken in a lot of cases.
-    // Since this code is intended to be used with SurfaceFlinger only,
-    // so it's okay...
-    
-    const vec4_t& v0 = c->vc.vBuffer[0].window;
-    const vec4_t& v1 = c->vc.vBuffer[1].window;
-    const vec4_t& v2 = c->vc.vBuffer[2].window;
-    const vec4_t& v3 = c->vc.vBuffer[3].window;
-    int l = min(v0.x, v2.x);
-    int b = min(v0.y, v2.y);
-    int r = max(v0.x, v2.x);
-    int t = max(v0.y, v2.y);
-    if ((l != min(v1.x, v3.x)) || (b != min(v1.y, v3.y)) ||
-        (r != max(v1.x, v3.x)) || (t != max(v1.y, v3.y))) {
-        LOGD_IF(DEBUG_COPYBIT, "geometry not a rectangle");
-        return false;
-    }
-
-    // fetch and transform texture coordinates
-    // NOTE: maybe it would be better to have a "compileElementsAll" method
-    // that would ensure all vertex data are fetched and transformed
-    const transform_t& tr = c->transforms.texture[0].transform; 
-    for (size_t i=0 ; i<4 ; i++) {
-        const GLubyte* tp = c->arrays.texture[0].element(i);
-        vertex_t* const v = &c->vc.vBuffer[i];
-        c->arrays.texture[0].fetch(c, v->texture[0].v, tp);
-        // FIXME: we should bail if q!=1
-        c->arrays.tex_transform[0](&tr, &v->texture[0], &v->texture[0]);
-    }
-    
-    const vec4_t& t0 = c->vc.vBuffer[0].texture[0];
-    const vec4_t& t1 = c->vc.vBuffer[1].texture[0];
-    const vec4_t& t2 = c->vc.vBuffer[2].texture[0];
-    const vec4_t& t3 = c->vc.vBuffer[3].texture[0];
-    int txl = min(t0.x, t2.x);
-    int txb = min(t0.y, t2.y);
-    int txr = max(t0.x, t2.x);
-    int txt = max(t0.y, t2.y);
-    if ((txl != min(t1.x, t3.x)) || (txb != min(t1.y, t3.y)) ||
-        (txr != max(t1.x, t3.x)) || (txt != max(t1.y, t3.y))) {
-        LOGD_IF(DEBUG_COPYBIT, "texcoord not a rectangle");
-        return false;
-    }
-    if ((txl != 0) || (txb != 0) ||
-        (txr != FIXED_ONE) || (txt != FIXED_ONE)) {
-        // we could probably handle this case, if we wanted to
-        LOGD_IF(DEBUG_COPYBIT, "texture is cropped: %08x,%08x,%08x,%08x",
-                txl, txb, txr, txt);
-        return false;
-    }
-
-    // at this point, we know we are dealing with a rectangle, so we 
-    // only need to consider 3 vertices for computing the jacobians
-    
-    const int dx01 = v1.x - v0.x;
-    const int dx02 = v2.x - v0.x;
-    const int dy01 = v1.y - v0.y;
-    const int dy02 = v2.y - v0.y;
-    const int ds01 = t1.S - t0.S;
-    const int ds02 = t2.S - t0.S;
-    const int dt01 = t1.T - t0.T;
-    const int dt02 = t2.T - t0.T;
-    const int area = dx01*dy02 - dy01*dx02;
-    int dsdx, dsdy, dtdx, dtdy;
-    if (area >= 0) {
-        dsdx = ds01*dy02 - ds02*dy01;
-        dtdx = dt01*dy02 - dt02*dy01;
-        dsdy = ds02*dx01 - ds01*dx02;
-        dtdy = dt02*dx01 - dt01*dx02;
-    } else {
-        dsdx = ds02*dy01 - ds01*dy02;
-        dtdx = dt02*dy01 - dt01*dy02;
-        dsdy = ds01*dx02 - ds02*dx01;
-        dtdy = dt01*dx02 - dt02*dx01;
-    }
-
-    // here we rely on the fact that we know the transform is
-    // a rigid-body transform AND that it can only rotate in 90 degrees
-    // increments
-
-    int transform = 0;
-    if (dsdx == 0) {
-        // 90 deg rotation case
-        // [ 0    dtdx  ]
-        // [ dsdx    0  ]
-        transform |= COPYBIT_TRANSFORM_ROT_90;
-        // FIXME: not sure if FLIP_H and FLIP_V shouldn't be inverted
-        if (dtdx > 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_H;
-        if (dsdy < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_V;
-    } else {
-        // [ dsdx    0  ]
-        // [ 0     dtdy ]
-        if (dsdx < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_H;
-        if (dtdy < 0)
-            transform |= COPYBIT_TRANSFORM_FLIP_V;
-    }
-
-    //LOGD("l=%d, b=%d, w=%d, h=%d, tr=%d", x, y, w, h, transform);
-    //LOGD("A=%f\tB=%f\nC=%f\tD=%f",
-    //      dsdx/65536.0, dtdx/65536.0, dsdy/65536.0, dtdy/65536.0);
-
-    int x = l >> 4;
-    int y = b >> 4;
-    int w = (r-l) >> 4;
-    int h = (t-b) >> 4;
-    texture_unit_t& u(c->textures.tmu[0]);
-    EGLTextureObject* textureObject = u.texture;
-    GLint tWidth = textureObject->surface.width;
-    GLint tHeight = textureObject->surface.height;
-    GLint crop_rect[4] = {0, tHeight, tWidth, -tHeight};
-    const GGLSurface& cbSurface = c->rasterizer.state.buffers.color.s;
-    y = cbSurface.height - (y + h);
-    return copybit(x, y, w, h, textureObject, crop_rect, transform, c);
-}
-
-/*
- * Try to drawTexiOESWithCopybit, return false if we fail.
- */
-
-bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c)
-{
-    // quickly process empty rects
-    if ((w|h) <= 0) {
-        return true;
-    }
-    if (!checkContext(c)) {
-        return false;
-    }
-    texture_unit_t& u(c->textures.tmu[0]);
-    EGLTextureObject* textureObject = u.texture;
-    return copybit(x, y, w, h, textureObject, textureObject->crop_rect, 0, c);
-}
-
-} // namespace android
-
diff --git a/opengl/libagl/copybit.h b/opengl/libagl/copybit.h
deleted file mode 100644
index b8b5afd..0000000
--- a/opengl/libagl/copybit.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-**
-** Copyright 2009, 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.
-*/
-
-#ifndef ANDROID_OPENGLES_COPYBIT_H
-#define ANDROID_OPENGLES_COPYBIT_H
-
-#include <stdlib.h>
-
-#include <GLES/gl.h>
-
-#include "TextureObjectManager.h"
-namespace android {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-bool drawTexiOESWithCopybit_impl(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c);
-
-bool drawTriangleFanWithCopybit_impl(ogles_context_t* c, GLint first,
-        GLsizei count);
-
-inline bool copybitQuickCheckContext(ogles_context_t* c) {
-        return  c->copybits.drawSurfaceBuffer != 0
-            && c->rasterizer.state.enabled_tmu == 1
-            && c->textures.tmu[0].texture->try_copybit;
-}
-
-/*
- * Tries to draw a drawTexiOES using copybit hardware.
- * Returns true if successful.
- */
-inline bool drawTexiOESWithCopybit(GLint x, GLint y, GLint z,
-        GLint w, GLint h, ogles_context_t* c) {
-    if (!copybitQuickCheckContext(c)) {
-    	return false;
-   	}
-   	
-   	return drawTexiOESWithCopybit_impl(x, y, z, w, h, c);
-}
-
-/*
- * Tries to draw a triangle fan using copybit hardware.
- * Returns true if successful.
- */
-inline bool drawTriangleFanWithCopybit(ogles_context_t* c, GLint first,
-        GLsizei count) {
-    /*
-     * We are looking for the glDrawArrays call made by SurfaceFlinger.
-     */
-
-    if ((count!=4) || first || !copybitQuickCheckContext(c))
-        return false;
-    
-    return drawTriangleFanWithCopybit_impl(c, first, count);
-}
-
-
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
-} // namespace android
-
-#endif // ANDROID_OPENGLES_COPYBIT_H
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 79c5ecb..460b74f 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -158,7 +158,6 @@
     virtual     EGLint      getSwapBehavior() const;
     virtual     EGLBoolean  swapBuffers();
     virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
-    virtual     EGLClientBuffer getRenderBuffer() const;
 protected:
     GGLSurface              depth;
 };
@@ -202,9 +201,6 @@
 {
     return EGL_FALSE;
 }
-EGLClientBuffer egl_surface_t::getRenderBuffer() const {
-    return 0;
-}
 
 // ----------------------------------------------------------------------------
 
@@ -213,7 +209,7 @@
     egl_window_surface_v2_t(
             EGLDisplay dpy, EGLConfig config,
             int32_t depthFormat,
-            android_native_window_t* window);
+            ANativeWindow* window);
 
     ~egl_window_surface_v2_t();
 
@@ -230,12 +226,11 @@
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
     virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
-    virtual     EGLClientBuffer  getRenderBuffer() const;
     
 private:
     status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
     status_t unlock(android_native_buffer_t* buf);
-    android_native_window_t*   nativeWindow;
+    ANativeWindow*   nativeWindow;
     android_native_buffer_t*   buffer;
     android_native_buffer_t*   previousBuffer;
     gralloc_module_t const*    module;
@@ -355,7 +350,7 @@
 egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
         EGLConfig config,
         int32_t depthFormat,
-        android_native_window_t* window)
+        ANativeWindow* window)
     : egl_surface_t(dpy, config, depthFormat), 
     nativeWindow(window), buffer(0), previousBuffer(0), module(0),
     blitengine(0), bits(NULL)
@@ -576,41 +571,44 @@
     buffer = 0;
 
     // dequeue a new buffer
-    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
-    
-    // TODO: lockBuffer should rather be executed when the very first
-    // direct rendering occurs.
-    nativeWindow->lockBuffer(nativeWindow, buffer);
-    
-    // reallocate the depth-buffer if needed
-    if ((width != buffer->width) || (height != buffer->height)) {
-        // TODO: we probably should reset the swap rect here
-        // if the window size has changed
-        width = buffer->width;
-        height = buffer->height;
-        if (depth.data) {
-            free(depth.data);
-            depth.width   = width;
-            depth.height  = height;
-            depth.stride  = buffer->stride;
-            depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
-            if (depth.data == 0) {
-                setError(EGL_BAD_ALLOC, EGL_FALSE);
-                return EGL_FALSE;
+    if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) == NO_ERROR) {
+
+        // TODO: lockBuffer should rather be executed when the very first
+        // direct rendering occurs.
+        nativeWindow->lockBuffer(nativeWindow, buffer);
+
+        // reallocate the depth-buffer if needed
+        if ((width != buffer->width) || (height != buffer->height)) {
+            // TODO: we probably should reset the swap rect here
+            // if the window size has changed
+            width = buffer->width;
+            height = buffer->height;
+            if (depth.data) {
+                free(depth.data);
+                depth.width   = width;
+                depth.height  = height;
+                depth.stride  = buffer->stride;
+                depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+                if (depth.data == 0) {
+                    setError(EGL_BAD_ALLOC, EGL_FALSE);
+                    return EGL_FALSE;
+                }
             }
         }
-    }
-    
-    // keep a reference on the buffer
-    buffer->common.incRef(&buffer->common);
 
-    // finally pin the buffer down
-    if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | 
-            GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
-        LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
-                buffer, buffer->width, buffer->height);
-        return setError(EGL_BAD_ACCESS, EGL_FALSE);
-        // FIXME: we should make sure we're not accessing the buffer anymore
+        // keep a reference on the buffer
+        buffer->common.incRef(&buffer->common);
+
+        // finally pin the buffer down
+        if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN |
+                GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
+            LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
+                    buffer, buffer->width, buffer->height);
+            return setError(EGL_BAD_ACCESS, EGL_FALSE);
+            // FIXME: we should make sure we're not accessing the buffer anymore
+        }
+    } else {
+        return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
     }
 
     return EGL_TRUE;
@@ -623,28 +621,6 @@
     return EGL_TRUE;
 }
 
-EGLClientBuffer egl_window_surface_v2_t::getRenderBuffer() const
-{
-    return buffer;
-}
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-static bool supportedCopybitsDestinationFormat(int format) {
-    // Hardware supported
-    switch (format) {
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        return true;
-    }
-    return false;
-}
-#endif
-
 EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
@@ -658,18 +634,6 @@
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    gl->copybits.drawSurfaceBuffer = 0;
-    if (gl->copybits.blitEngine != NULL) {
-        if (supportedCopybitsDestinationFormat(buffer.format)) {
-            buffer_handle_t handle = this->buffer->handle;
-            if (handle != NULL) {
-                gl->copybits.drawSurfaceBuffer = this->buffer;
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return EGL_TRUE;
 }
 EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
@@ -883,7 +847,6 @@
         // "KHR_image_pixmap "
         "EGL_ANDROID_image_native_buffer "
         "EGL_ANDROID_swap_rectangle "
-        "EGL_ANDROID_get_render_buffer "
         ;
 
 // ----------------------------------------------------------------------------
@@ -936,8 +899,6 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "eglGetRenderBufferANDROID", 
-            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
 /*
@@ -1300,7 +1261,7 @@
     if (!(surfaceType & EGL_WINDOW_BIT))
         return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
 
-    if (static_cast<android_native_window_t*>(window)->common.magic !=
+    if (static_cast<ANativeWindow*>(window)->common.magic !=
             ANDROID_NATIVE_WINDOW_MAGIC) {
         return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
     }
@@ -1323,7 +1284,7 @@
 
     egl_surface_t* surface;
     surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
-            static_cast<android_native_window_t*>(window));
+            static_cast<ANativeWindow*>(window));
 
     if (!surface->initCheck()) {
         // there was a problem in the ctor, the error
@@ -1525,8 +1486,13 @@
     }
 
     if (ggl_unlikely(attrib_list==0)) {
-        *num_config = 0;
-        return EGL_TRUE;
+        /*
+         * A NULL attrib_list should be treated as though it was an empty
+         * one (terminated with EGL_NONE) as defined in
+         * section 3.4.1 "Querying Configurations" in the EGL specification.
+         */
+        static const EGLint dummy = EGL_NONE;
+        attrib_list = &dummy;
     }
 
     int numAttributes = 0;
@@ -2150,18 +2116,3 @@
 
     return EGL_TRUE;
 }
-
-EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw)
-{
-    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
-        return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0);
-
-    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
-    if (!d->isValid())
-        return setError(EGL_BAD_SURFACE, (EGLClientBuffer)0);
-    if (d->dpy != dpy)
-        return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0);
-
-    // post the surface
-    return d->getRenderBuffer();
-}
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 27bb545..a0f720a 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -28,10 +28,6 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include <hardware/copybit.h>
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -101,35 +97,6 @@
     // OpenGL enables dithering by default
     c->rasterizer.procs.enable(c, GL_DITHER);
 
-    c->copybits.blitEngine = NULL;
-    c->copybits.minScale = 0;
-    c->copybits.maxScale = 0;
-    c->copybits.drawSurfaceBuffer = 0;
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    hw_module_t const* module;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        struct copybit_device_t* copyBits;
-        if (copybit_open(module, &copyBits) == 0) {
-            c->copybits.blitEngine = copyBits;
-            {
-                int minLim = copyBits->get(copyBits,
-                        COPYBIT_MINIFICATION_LIMIT);
-                if (minLim != -EINVAL && minLim > 0) {
-                    c->copybits.minScale = (1 << 16) / minLim;
-                }
-            }
-            {
-                int magLim = copyBits->get(copyBits,
-                        COPYBIT_MAGNIFICATION_LIMIT);
-                if (magLim != -EINVAL && magLim > 0) {
-                    c->copybits.maxScale = min(32*1024-1, magLim) << 16;
-                }
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return c;
 }
 
@@ -144,11 +111,6 @@
     c->bufferObjectManager->decStrong(c);
     ggl_uninit_context(&(c->rasterizer));
     free(c->rasterizer.base);
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (c->copybits.blitEngine != NULL) {
-        copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void _ogles_error(ogles_context_t* c, GLenum error)
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index d67612e..eb96895 100644
--- a/opengl/libagl/texture.cpp
+++ b/opengl/libagl/texture.cpp
@@ -26,10 +26,6 @@
 #include <private/ui/android_natives_priv.h>
 #include <ETC1/etc1.h>
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include "copybit.h"
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -763,17 +759,10 @@
 static void drawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h,
         ogles_context_t* c)
 {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (drawTexiOESWithCopybit(gglFixedToIntRound(x),
-            gglFixedToIntRound(y), gglFixedToIntRound(z),
-            gglFixedToIntRound(w), gglFixedToIntRound(h), c)) {
-        return;
-    }
-#else
     // quickly reject empty rects
     if ((w|h) <= 0)
         return;
-#endif
+
     drawTexxOESImp(x, y, z, w, h, c);
 }
 
@@ -785,11 +774,6 @@
     // which is a lot faster.
 
     if (ggl_likely(c->rasterizer.state.enabled_tmu == 1)) {
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-        if (drawTexiOESWithCopybit(x, y, z, w, h, c)) {
-            return;
-        }
-#endif
         const int tmu = 0;
         texture_unit_t& u(c->textures.tmu[tmu]);
         EGLTextureObject* textureObject = u.texture;
@@ -797,9 +781,7 @@
         const GLint Hcr = textureObject->crop_rect[3];
 
         if ((w == Wcr) && (h == -Hcr)) {
-#ifndef LIBAGL_USE_GRALLOC_COPYBITS
             if ((w|h) <= 0) return; // quickly reject empty rects
-#endif
 
             if (u.dirty) {
                 c->rasterizer.procs.activeTexture(c, tmu);
@@ -1646,13 +1628,6 @@
     // bind it to the texture unit
     sp<EGLTextureObject> tex = getAndBindActiveTextureObject(c);
     tex->setImage(native_buffer);
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    tex->try_copybit = false;
-    if (c->copybits.blitEngine != NULL) {
-        tex->try_copybit = true;
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void glEGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index 6b7020f..ae924cd 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -6,10 +6,11 @@
 
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= 	\
-	EGL/egl.cpp 	\
-	EGL/hooks.cpp 	\
-	EGL/Loader.cpp 	\
+LOCAL_SRC_FILES:= 	       \
+	EGL/egl.cpp 	       \
+	EGL/getProcAddress.cpp.arm \
+	EGL/hooks.cpp 	       \
+	EGL/Loader.cpp 	       \
 #
 
 LOCAL_SHARED_LIBRARIES += libcutils libutils
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index de740a3..df21358 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -37,12 +37,13 @@
 #include <cutils/memory.h>
 
 #include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
 
 #include "hooks.h"
 #include "egl_impl.h"
 #include "Loader.h"
 
-#define MAKE_CONFIG(_impl, _index)  ((EGLConfig)(((_impl)<<24) | (_index)))
 #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r)
 
 // ----------------------------------------------------------------------------
@@ -60,7 +61,6 @@
         "EGL_KHR_image_pixmap "
         "EGL_ANDROID_image_native_buffer "
         "EGL_ANDROID_swap_rectangle "
-        "EGL_ANDROID_get_render_buffer "
         ;
 
 // ----------------------------------------------------------------------------
@@ -143,6 +143,22 @@
 SortedVector<egl_object_t*> egl_object_t::sObjects;
 Mutex egl_object_t::sLock;
 
+
+struct egl_config_t {
+    egl_config_t() {}
+    egl_config_t(int impl, EGLConfig config)
+        : impl(impl), config(config), configId(0), implConfigId(0) { }
+    int         impl;           // the implementation this config is for
+    EGLConfig   config;         // the implementation's EGLConfig
+    EGLint      configId;       // our CONFIG_ID
+    EGLint      implConfigId;   // the implementation's CONFIG_ID
+    inline bool operator < (const egl_config_t& rhs) const {
+        if (impl < rhs.impl) return true;
+        if (impl > rhs.impl) return false;
+        return config < rhs.config;
+    }
+};
+
 struct egl_display_t {
     enum { NOT_INITIALIZED, INITIALIZED, TERMINATED };
     
@@ -163,13 +179,14 @@
         strings_t   queryString;
     };
 
-    uint32_t    magic;
-    DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS];
-    EGLint      numTotalConfigs;
-    uint32_t    refs;
-    Mutex       lock;
+    uint32_t        magic;
+    DisplayImpl     disp[IMPL_NUM_IMPLEMENTATIONS];
+    EGLint          numTotalConfigs;
+    egl_config_t*   configs;
+    uint32_t        refs;
+    Mutex           lock;
     
-    egl_display_t() : magic('_dpy'), numTotalConfigs(0) { }
+    egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { }
     ~egl_display_t() { magic = 0; }
     inline bool isValid() const { return magic == '_dpy'; }
     inline bool isAlive() const { return isValid(); }
@@ -179,14 +196,15 @@
 {
     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
 
-    egl_surface_t(EGLDisplay dpy, EGLSurface surface,
+    egl_surface_t(EGLDisplay dpy, EGLSurface surface, EGLConfig config,
             int impl, egl_connection_t const* cnx) 
-    : dpy(dpy), surface(surface), impl(impl), cnx(cnx) {
+    : dpy(dpy), surface(surface), config(config), impl(impl), cnx(cnx) {
     }
     ~egl_surface_t() {
     }
     EGLDisplay                  dpy;
     EGLSurface                  surface;
+    EGLConfig                   config;
     int                         impl;
     egl_connection_t const*     cnx;
 };
@@ -195,7 +213,7 @@
 {
     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
     
-    egl_context_t(EGLDisplay dpy, EGLContext context,
+    egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
             int impl, egl_connection_t const* cnx, int version) 
     : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx),
       version(version)
@@ -203,6 +221,7 @@
     }
     EGLDisplay                  dpy;
     EGLContext                  context;
+    EGLConfig                   config;
     EGLSurface                  read;
     EGLSurface                  draw;
     int                         impl;
@@ -220,7 +239,7 @@
         memset(images, 0, sizeof(images));
     }
     EGLDisplay dpy;
-    EGLConfig context;
+    EGLContext context;
     EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
 };
 
@@ -239,7 +258,7 @@
 
 // ----------------------------------------------------------------------------
 
-egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
+static egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
 static egl_display_t gDisplay[NUM_DISPLAYS];
 static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t gEGLThreadLocalStorageKey = -1;
@@ -354,7 +373,7 @@
 {
     while (first <= last) {
         int mid = (first + last) / 2;
-        if (key > sortedArray[mid]) { 
+        if (sortedArray[mid] < key) {
             first = mid + 1;
         } else if (key < sortedArray[mid]) { 
             last = mid - 1;
@@ -365,26 +384,11 @@
     return -1;
 }
 
-static EGLint configToUniqueId(egl_display_t const* dp, int i, int index) 
-{
-    // NOTE: this mapping works only if we have no more than two EGLimpl
-    return (i>0 ? dp->disp[0].numConfigs : 0) + index;
-}
-
-static void uniqueIdToConfig(egl_display_t const* dp, EGLint configId,
-        int& i, int& index) 
-{
-    // NOTE: this mapping works only if we have no more than two EGLimpl
-    size_t numConfigs = dp->disp[0].numConfigs;
-    i = configId / numConfigs;
-    index = configId % numConfigs;
-}
-
 static int cmp_configs(const void* a, const void *b)
 {
-    EGLConfig c0 = *(EGLConfig const *)a;
-    EGLConfig c1 = *(EGLConfig const *)b;
-    return c0<c1 ? -1 : (c0>c1 ? 1 : 0);
+    const egl_config_t& c0 = *(egl_config_t const *)a;
+    const egl_config_t& c1 = *(egl_config_t const *)b;
+    return c0<c1 ? -1 : (c1<c0 ? 1 : 0);
 }
 
 struct extention_map_t {
@@ -403,11 +407,13 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "eglGetRenderBufferANDROID", 
-            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
-static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS];
+extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
+
+// accesses protected by gInitDriverMutex
+static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> gGLExtentionMap;
+static int gGLExtentionSlot = 0;
 
 static void(*findProcAddress(const char* name,
         const extention_map_t* map, size_t n))() 
@@ -477,20 +483,15 @@
 
 static egl_connection_t* validate_display_config(
         EGLDisplay dpy, EGLConfig config,
-        egl_display_t const*& dp, int& impl, int& index)
+        egl_display_t const*& dp)
 {
     dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL);
 
-    impl = uintptr_t(config)>>24;
-    if (uint32_t(impl) >= IMPL_NUM_IMPLEMENTATIONS) {
-        return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
-    } 
-    index = uintptr_t(config) & 0xFFFFFF;
-    if (index >= dp->disp[impl].numConfigs) {
+    if (intptr_t(config) >= dp->numTotalConfigs) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
     }
-    egl_connection_t* const cnx = &gEGLImpl[impl];
+    egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl];
     if (cnx->dso == 0) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
     }
@@ -718,11 +719,6 @@
                             dp->disp[i].dpy, dp->disp[i].config, n,
                             &dp->disp[i].numConfigs))
                     {
-                        // sort the configurations so we can do binary searches
-                        qsort(  dp->disp[i].config,
-                                dp->disp[i].numConfigs,
-                                sizeof(EGLConfig), cmp_configs);
-
                         dp->numTotalConfigs += n;
                         res = EGL_TRUE;
                     }
@@ -732,6 +728,30 @@
     }
 
     if (res == EGL_TRUE) {
+        dp->configs = new egl_config_t[ dp->numTotalConfigs ];
+        for (int i=0, k=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
+            egl_connection_t* const cnx = &gEGLImpl[i];
+            if (cnx->dso && cnx->major>=0 && cnx->minor>=0) {
+                for (int j=0 ; j<dp->disp[i].numConfigs ; j++) {
+                    dp->configs[k].impl = i;
+                    dp->configs[k].config = dp->disp[i].config[j];
+                    dp->configs[k].configId = k + 1; // CONFIG_ID start at 1
+                    // store the implementation's CONFIG_ID
+                    cnx->egl.eglGetConfigAttrib(
+                            dp->disp[i].dpy,
+                            dp->disp[i].config[j],
+                            EGL_CONFIG_ID,
+                            &dp->configs[k].implConfigId);
+                    k++;
+                }
+            }
+        }
+
+        // sort our configurations so we can do binary-searches
+        qsort(  dp->configs,
+                dp->numTotalConfigs,
+                sizeof(egl_config_t), cmp_configs);
+
         dp->refs++;
         if (major != NULL) *major = VERSION_MAJOR;
         if (minor != NULL) *minor = VERSION_MINOR;
@@ -784,6 +804,7 @@
     
     dp->refs--;
     dp->numTotalConfigs = 0;
+    delete [] dp->configs;
     clearTLS();
     return res;
 }
@@ -804,14 +825,13 @@
         *num_config = numConfigs;
         return EGL_TRUE;
     }
+
     GLint n = 0;
-    for (int j=0 ; j<IMPL_NUM_IMPLEMENTATIONS ; j++) {
-        for (int i=0 ; i<dp->disp[j].numConfigs && config_size ; i++) {
-            *configs++ = MAKE_CONFIG(j, i);
-            config_size--;
-            n++;
-        }
-    }    
+    for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) {
+        *configs++ = EGLConfig(i);
+        config_size--;
+        n++;
+    }
     
     *num_config = n;
     return EGL_TRUE;
@@ -834,7 +854,7 @@
 
     
     // It is unfortunate, but we need to remap the EGL_CONFIG_IDs, 
-    // to do  this, we have to go through the attrib_list array once
+    // to do this, we have to go through the attrib_list array once
     // to figure out both its size and if it contains an EGL_CONFIG_ID
     // key. If so, the full array is copied and patched.
     // NOTE: we assume that there can be only one occurrence
@@ -843,8 +863,7 @@
     EGLint patch_index = -1;
     GLint attr;
     size_t size = 0;
-
-    if (attrib_list != NULL) {
+    if (attrib_list) {
         while ((attr=attrib_list[size]) != EGL_NONE) {
             if (attr == EGL_CONFIG_ID)
                 patch_index = size;
@@ -859,16 +878,20 @@
         memcpy(new_list, attrib_list, size*sizeof(EGLint));
 
         // patch the requested EGL_CONFIG_ID
-        int i, index;
+        bool found = false;
+        EGLConfig ourConfig(0);
         EGLint& configId(new_list[patch_index+1]);
-        uniqueIdToConfig(dp, configId, i, index);
-        
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            cnx->egl.eglGetConfigAttrib(
-                    dp->disp[i].dpy, dp->disp[i].config[index], 
-                    EGL_CONFIG_ID, &configId);
+        for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) {
+            if (dp->configs[i].configId == configId) {
+                ourConfig = EGLConfig(i);
+                configId = dp->configs[i].implConfigId;
+                found = true;
+                break;
+            }
+        }
 
+        egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl];
+        if (found && cnx->dso) {
             // and switch to the new list
             attrib_list = const_cast<const EGLint *>(new_list);
 
@@ -881,12 +904,13 @@
             // which one.
 
             res = cnx->egl.eglChooseConfig(
-                    dp->disp[i].dpy, attrib_list, configs, config_size, &n);
+                    dp->disp[ dp->configs[intptr_t(ourConfig)].impl ].dpy,
+                    attrib_list, configs, config_size, &n);
             if (res && n>0) {
                 // n has to be 0 or 1, by construction, and we already know
                 // which config it will return (since there can be only one).
                 if (configs) {
-                    configs[0] = MAKE_CONFIG(i, index);
+                    configs[0] = ourConfig;
                 }
                 *num_config = 1;
             }
@@ -896,6 +920,7 @@
         return res;
     }
 
+
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
@@ -903,15 +928,14 @@
                     dp->disp[i].dpy, attrib_list, configs, config_size, &n)) {
                 if (configs) {
                     // now we need to convert these client EGLConfig to our
-                    // internal EGLConfig format. This is done in O(n log n).
+                    // internal EGLConfig format.
+                    // This is done in O(n Log(n)) time.
                     for (int j=0 ; j<n ; j++) {
-                        int index = binarySearch<EGLConfig>(
-                                dp->disp[i].config, 0,
-                                dp->disp[i].numConfigs-1, configs[j]);
+                        egl_config_t key(i, configs[j]);
+                        intptr_t index = binarySearch<egl_config_t>(
+                                dp->configs, 0, dp->numTotalConfigs, key);
                         if (index >= 0) {
-                            if (configs) {
-                                configs[j] = MAKE_CONFIG(i, index);
-                            }
+                            configs[j] = EGLConfig(index);
                         } else {
                             return setError(EGL_BAD_CONFIG, EGL_FALSE);
                         }
@@ -931,18 +955,16 @@
         EGLint attribute, EGLint *value)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (!cnx) return EGL_FALSE;
     
     if (attribute == EGL_CONFIG_ID) {
-        // EGL_CONFIG_IDs must be unique, just use the order of the selected
-        // EGLConfig.
-        *value = configToUniqueId(dp, i, index);
+        *value = dp->configs[intptr_t(config)].configId;
         return EGL_TRUE;
     }
     return cnx->egl.eglGetConfigAttrib(
-            dp->disp[i].dpy, dp->disp[i].config[index], attribute, value);
+            dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+            dp->configs[intptr_t(config)].config, attribute, value);
 }
 
 // ----------------------------------------------------------------------------
@@ -954,13 +976,14 @@
                                     const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
-                dp->disp[i].dpy, dp->disp[i].config[index], window, attrib_list);       
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config, window, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+                    dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
     }
@@ -972,13 +995,14 @@
                                     const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
-                dp->disp[i].dpy, dp->disp[i].config[index], pixmap, attrib_list);
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config, pixmap, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+                    dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
     }
@@ -989,13 +1013,14 @@
                                     const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
-                dp->disp[i].dpy, dp->disp[i].config[index], attrib_list);
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+                    dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
     }
@@ -1031,27 +1056,35 @@
     egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
 
-    return s->cnx->egl.eglQuerySurface(
-            dp->disp[s->impl].dpy, s->surface, attribute, value);
+    EGLBoolean result(EGL_TRUE);
+    if (attribute == EGL_CONFIG_ID) {
+        // We need to remap EGL_CONFIG_IDs
+        *value = dp->configs[intptr_t(s->config)].configId;
+    } else {
+        result = s->cnx->egl.eglQuerySurface(
+                dp->disp[s->impl].dpy, s->surface, attribute, value);
+    }
+
+    return result;
 }
 
 // ----------------------------------------------------------------------------
-// contextes
+// Contexts
 // ----------------------------------------------------------------------------
 
 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
                             EGLContext share_list, const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         if (share_list != EGL_NO_CONTEXT) {
             egl_context_t* const c = get_context(share_list);
             share_list = c->context;
         }
         EGLContext context = cnx->egl.eglCreateContext(
-                dp->disp[i].dpy, dp->disp[i].config[index],
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config,
                 share_list, attrib_list);
         if (context != EGL_NO_CONTEXT) {
             // figure out if it's a GLESv1 or GLESv2
@@ -1069,7 +1102,8 @@
                     }
                 };
             }
-            egl_context_t* c = new egl_context_t(dpy, context, i, cnx, version);
+            egl_context_t* c = new egl_context_t(dpy, context, config,
+                    dp->configs[intptr_t(config)].impl, cnx, version);
             return c;
         }
     }
@@ -1214,8 +1248,16 @@
     egl_display_t const * const dp = get_display(dpy);
     egl_context_t * const c = get_context(ctx);
 
-    return c->cnx->egl.eglQueryContext(
-            dp->disp[c->impl].dpy, c->context, attribute, value);
+    EGLBoolean result(EGL_TRUE);
+    if (attribute == EGL_CONFIG_ID) {
+        *value = dp->configs[intptr_t(c->config)].configId;
+    } else {
+        // We need to remap EGL_CONFIG_IDs
+        result = c->cnx->egl.eglQueryContext(
+                dp->disp[c->impl].dpy, c->context, attribute, value);
+    }
+
+    return result;
 }
 
 EGLContext eglGetCurrentContext(void)
@@ -1330,55 +1372,55 @@
     addr = findProcAddress(procname, gExtentionMap, NELEM(gExtentionMap));
     if (addr) return addr;
 
-    return NULL; // TODO: finish implementation below
+    // this protects accesses to gGLExtentionMap and gGLExtentionSlot
+    pthread_mutex_lock(&gInitDriverMutex);
 
-    addr = findProcAddress(procname, gGLExtentionMap, NELEM(gGLExtentionMap));
-    if (addr) return addr;
-    
-    addr = 0;
-    int slot = -1;
-    for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            if (cnx->egl.eglGetProcAddress) {
-                addr = cnx->egl.eglGetProcAddress(procname);
-                if (addr) {
-                    if (slot == -1) {
-                        slot = 0; // XXX: find free slot
-                        if (slot == -1) {
-                            addr = 0;
-                            break;
-                        }
-                    }
-                    //cnx->hooks->ext.extensions[slot] = addr;
+        /*
+         * Since eglGetProcAddress() is not associated to anything, it needs
+         * to return a function pointer that "works" regardless of what
+         * the current context is.
+         *
+         * For this reason, we return a "forwarder", a small stub that takes
+         * care of calling the function associated with the context
+         * currently bound.
+         *
+         * We first look for extensions we've already resolved, if we're seeing
+         * this extension for the first time, we go through all our
+         * implementations and call eglGetProcAddress() and record the
+         * result in the appropriate implementation hooks and return the
+         * address of the forwarder corresponding to that hook set.
+         *
+         */
+
+        const String8 name(procname);
+        addr = gGLExtentionMap.valueFor(name);
+        const int slot = gGLExtentionSlot;
+
+        LOGE_IF(slot >= MAX_NUMBER_OF_GL_EXTENSIONS,
+                "no more slots for eglGetProcAddress(\"%s\")",
+                procname);
+
+        if (!addr && (slot < MAX_NUMBER_OF_GL_EXTENSIONS)) {
+            bool found = false;
+            for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
+                egl_connection_t* const cnx = &gEGLImpl[i];
+                if (cnx->dso && cnx->egl.eglGetProcAddress) {
+                    found = true;
+                    // Extensions are independent of the bound context
+                    cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] =
+                    cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] =
+                            cnx->egl.eglGetProcAddress(procname);
                 }
             }
+            if (found) {
+                addr = gExtensionForwarders[slot];
+                gGLExtentionMap.add(name, addr);
+                gGLExtentionSlot++;
+            }
         }
-    }
-    
-    if (slot >= 0) {
-        addr = 0; // XXX: address of stub 'slot'
-        gGLExtentionMap[slot].name = strdup(procname);
-        gGLExtentionMap[slot].address = addr;
-    }
-    
-    return addr;
 
-    
-    /*
-     *  TODO: For OpenGL ES extensions, we must generate a stub
-     *  that looks like
-     *      mov     r12, #0xFFFF0FFF
-     *      ldr     r12, [r12, #-15]
-     *      ldr     r12, [r12, #TLS_SLOT_OPENGL_API*4]
-     *      mov     r12, [r12, #api_offset]
-     *      ldrne   pc, r12
-     *      mov     pc, #unsupported_extension
-     * 
-     *  and write the address of the extension in *all*
-     *  gl_hooks_t::gl_ext_t at offset "api_offset" from gl_hooks_t
-     * 
-     */
+    pthread_mutex_unlock(&gInitDriverMutex);
+    return addr;
 }
 
 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
@@ -1587,13 +1629,13 @@
           EGLConfig config, const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (!cnx) return EGL_FALSE;
     if (cnx->egl.eglCreatePbufferFromClientBuffer) {
         return cnx->egl.eglCreatePbufferFromClientBuffer(
-                dp->disp[i].dpy, buftype, buffer, 
-                dp->disp[i].config[index], attrib_list);
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                buftype, buffer,
+                dp->configs[intptr_t(config)].config, attrib_list);
     }
     return setError(EGL_BAD_CONFIG, EGL_NO_SURFACE);
 }
@@ -1727,7 +1769,7 @@
          egl_connection_t* const cnx = &gEGLImpl[i];
          if (image->images[i] != EGL_NO_IMAGE_KHR) {
              if (cnx->dso) {
-                 if (cnx->egl.eglCreateImageKHR) {
+                 if (cnx->egl.eglDestroyImageKHR) {
                      if (cnx->egl.eglDestroyImageKHR(
                              dp->disp[i].dpy, image->images[i])) {
                          success = true;
@@ -1765,19 +1807,3 @@
     }
     return setError(EGL_BAD_DISPLAY, NULL);
 }
-
-EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw)
-{
-    SurfaceRef _s(draw);
-    if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLClientBuffer*)0);
-
-    if (!validate_display_surface(dpy, draw))
-        return 0;    
-    egl_display_t const * const dp = get_display(dpy);
-    egl_surface_t const * const s = get_surface(draw);
-    if (s->cnx->egl.eglGetRenderBufferANDROID) {
-        return s->cnx->egl.eglGetRenderBufferANDROID(
-                dp->disp[s->impl].dpy, s->surface);
-    }
-    return setError(EGL_BAD_DISPLAY, (EGLClientBuffer*)0);
-}
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
new file mode 100644
index 0000000..dcf8735
--- /dev/null
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -0,0 +1,122 @@
+/*
+ ** Copyright 2009, 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.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+
+#include "hooks.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+#undef API_ENTRY
+#undef CALL_GL_EXTENSION_API
+#undef GL_EXTENSION
+#undef GL_EXTENSION_NAME
+#undef GL_EXTENSION_ARRAY
+#undef GL_EXTENSION_LIST
+#undef GET_TLS
+
+#if defined(__arm__)
+
+    #ifdef HAVE_ARM_TLS_REGISTER
+        #define GET_TLS(reg) \
+            "mrc p15, 0, " #reg ", c13, c0, 3 \n"
+    #else
+        #define GET_TLS(reg) \
+            "mov   " #reg ", #0xFFFF0FFF      \n"  \
+            "ldr   " #reg ", [" #reg ", #-15] \n"
+    #endif
+
+    #define API_ENTRY(_api) __attribute__((naked)) _api
+
+    #define CALL_GL_EXTENSION_API(_api)                         \
+         asm volatile(                                          \
+            GET_TLS(r12)                                        \
+            "ldr   r12, [r12, %[tls]] \n"                       \
+            "cmp   r12, #0            \n"                       \
+            "ldrne r12, [r12, %[api]] \n"                       \
+            "cmpne r12, #0            \n"                       \
+            "bxne  r12                \n"                       \
+            "bx    lr                 \n"                       \
+            :                                                   \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
+              [api] "J"(__builtin_offsetof(gl_hooks_t,          \
+                                      ext.extensions[_api]))    \
+            :                                                   \
+            );
+
+    #define GL_EXTENSION_NAME(_n)   __glExtFwd##_n
+
+    #define GL_EXTENSION(_n)                         \
+        void API_ENTRY(GL_EXTENSION_NAME(_n))() {    \
+            CALL_GL_EXTENSION_API(_n);               \
+        }
+
+
+#else
+
+    #define GL_EXTENSION_NAME(_n) NULL
+
+    #define GL_EXTENSION(_n)
+
+    #warning "eglGetProcAddress() partially supported on this architecture"
+
+#endif
+
+#define GL_EXTENSION_LIST(name) \
+        name(0)   name(1)   name(2)   name(3)   \
+        name(4)   name(5)   name(6)   name(7)   \
+        name(8)   name(9)   name(10)  name(11)  \
+        name(12)  name(13)  name(14)  name(15)  \
+        name(16)  name(17)  name(18)  name(19)  \
+        name(20)  name(21)  name(22)  name(23)  \
+        name(24)  name(25)  name(26)  name(27)  \
+        name(28)  name(29)  name(30)  name(31)  \
+        name(32)  name(33)  name(34)  name(35)  \
+        name(36)  name(37)  name(38)  name(39)  \
+        name(40)  name(41)  name(42)  name(43)  \
+        name(44)  name(45)  name(46)  name(47)  \
+        name(48)  name(49)  name(50)  name(51)  \
+        name(52)  name(53)  name(54)  name(55)  \
+        name(56)  name(57)  name(58)  name(59)  \
+        name(60)  name(61)  name(62)  name(63)
+
+
+GL_EXTENSION_LIST( GL_EXTENSION )
+
+#define GL_EXTENSION_ARRAY(_n)  GL_EXTENSION_NAME(_n),
+
+extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS] = {
+        GL_EXTENSION_LIST( GL_EXTENSION_ARRAY )
+ };
+
+#undef GET_TLS
+#undef GL_EXTENSION_LIST
+#undef GL_EXTENSION_ARRAY
+#undef GL_EXTENSION_NAME
+#undef GL_EXTENSION
+#undef API_ENTRY
+#undef CALL_GL_EXTENSION_API
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
diff --git a/opengl/libs/GLES2/gl2_api.in b/opengl/libs/GLES2/gl2_api.in
index 9c2e69a..5164450 100644
--- a/opengl/libs/GLES2/gl2_api.in
+++ b/opengl/libs/GLES2/gl2_api.in
@@ -4,7 +4,7 @@
 void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
     CALL_GL_API(glAttachShader, program, shader);
 }
-void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const char* name) {
+void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const GLchar* name) {
     CALL_GL_API(glBindAttribLocation, program, index, name);
 }
 void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
@@ -34,10 +34,10 @@
 void API_ENTRY(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
     CALL_GL_API(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha);
 }
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
+void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
     CALL_GL_API(glBufferData, target, size, data, usage);
 }
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
+void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
     CALL_GL_API(glBufferSubData, target, offset, size, data);
 }
 GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) {
@@ -61,10 +61,10 @@
 void API_ENTRY(glCompileShader)(GLuint shader) {
     CALL_GL_API(glCompileShader, shader);
 }
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
 }
-void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
 }
 void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
@@ -121,7 +121,7 @@
 void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
     CALL_GL_API(glDrawArrays, mode, first, count);
 }
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const void* indices) {
+void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
     CALL_GL_API(glDrawElements, mode, count, type, indices);
 }
 void API_ENTRY(glEnable)(GLenum cap) {
@@ -160,16 +160,16 @@
 void API_ENTRY(glGenTextures)(GLsizei n, GLuint* textures) {
     CALL_GL_API(glGenTextures, n, textures);
 }
-void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) {
+void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
     CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
 }
-void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) {
+void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
     CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
 }
 void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
     CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
 }
-int API_ENTRY(glGetAttribLocation)(GLuint program, const char* name) {
+int API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar* name) {
     CALL_GL_API_RETURN(glGetAttribLocation, program, name);
 }
 void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params) {
@@ -193,7 +193,7 @@
 void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint* params) {
     CALL_GL_API(glGetProgramiv, program, pname, params);
 }
-void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) {
+void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
     CALL_GL_API(glGetProgramInfoLog, program, bufsize, length, infolog);
 }
 void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
@@ -202,13 +202,13 @@
 void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint* params) {
     CALL_GL_API(glGetShaderiv, shader, pname, params);
 }
-void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) {
+void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
     CALL_GL_API(glGetShaderInfoLog, shader, bufsize, length, infolog);
 }
 void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
     CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
 }
-void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
+void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) {
     CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
 }
 const GLubyte* API_ENTRY(glGetString)(GLenum name) {
@@ -226,7 +226,7 @@
 void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params) {
     CALL_GL_API(glGetUniformiv, program, location, params);
 }
-int API_ENTRY(glGetUniformLocation)(GLuint program, const char* name) {
+int API_ENTRY(glGetUniformLocation)(GLuint program, const GLchar* name) {
     CALL_GL_API_RETURN(glGetUniformLocation, program, name);
 }
 void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params) {
@@ -235,7 +235,7 @@
 void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params) {
     CALL_GL_API(glGetVertexAttribiv, index, pname, params);
 }
-void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer) {
+void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer) {
     CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
 }
 void API_ENTRY(glHint)(GLenum target, GLenum mode) {
@@ -274,7 +274,7 @@
 void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
     CALL_GL_API(glPolygonOffset, factor, units);
 }
-void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
+void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
     CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
 }
 void API_ENTRY(glReleaseShaderCompiler)(void) {
@@ -289,10 +289,10 @@
 void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
     CALL_GL_API(glScissor, x, y, width, height);
 }
-void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) {
+void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) {
     CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
 }
-void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length) {
+void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
     CALL_GL_API(glShaderSource, shader, count, string, length);
 }
 void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
@@ -313,7 +313,7 @@
 void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
     CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
 }
-void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
 }
 void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
@@ -328,7 +328,7 @@
 void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params) {
     CALL_GL_API(glTexParameteriv, target, pname, params);
 }
-void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) {
+void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
 }
 void API_ENTRY(glUniform1f)(GLint location, GLfloat x) {
@@ -418,7 +418,7 @@
 void API_ENTRY(glVertexAttrib4fv)(GLuint indx, const GLfloat* values) {
     CALL_GL_API(glVertexAttrib4fv, indx, values);
 }
-void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) {
+void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) {
     CALL_GL_API(glVertexAttribPointer, indx, size, type, normalized, stride, ptr);
 }
 void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
diff --git a/opengl/libs/GLES2/gl2ext_api.in b/opengl/libs/GLES2/gl2ext_api.in
index 6eeecb3..e965625 100644
--- a/opengl/libs/GLES2/gl2ext_api.in
+++ b/opengl/libs/GLES2/gl2ext_api.in
@@ -4,10 +4,10 @@
 void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
     CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
 }
-void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) {
+void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) {
     CALL_GL_API(glGetProgramBinaryOES, program, bufSize, length, binaryFormat, binary);
 }
-void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const void *binary, GLint length) {
+void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length) {
     CALL_GL_API(glProgramBinaryOES, program, binaryFormat, binary, length);
 }
 void* API_ENTRY(glMapBufferOES)(GLenum target, GLenum access) {
@@ -16,40 +16,52 @@
 GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
     CALL_GL_API_RETURN(glUnmapBufferOES, target);
 }
-void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) {
+void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, GLvoid** params) {
     CALL_GL_API(glGetBufferPointervOES, target, pname, params);
 }
-void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
+void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexImage3DOES, target, level, internalformat, width, height, depth, border, format, type, pixels);
 }
-void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
+void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
 }
 void API_ENTRY(glCopyTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
     CALL_GL_API(glCopyTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, x, y, width, height);
 }
-void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexImage3DOES, target, level, internalformat, width, height, depth, border, imageSize, data);
 }
-void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 }
 void API_ENTRY(glFramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
     CALL_GL_API(glFramebufferTexture3DOES, target, attachment, textarget, texture, level, zoffset);
 }
+void API_ENTRY(glBindVertexArrayOES)(GLuint array) {
+    CALL_GL_API(glBindVertexArrayOES, array);
+}
+void API_ENTRY(glDeleteVertexArraysOES)(GLsizei n, const GLuint *arrays) {
+    CALL_GL_API(glDeleteVertexArraysOES, n, arrays);
+}
+void API_ENTRY(glGenVertexArraysOES)(GLsizei n, GLuint *arrays) {
+    CALL_GL_API(glGenVertexArraysOES, n, arrays);
+}
+GLboolean API_ENTRY(glIsVertexArrayOES)(GLuint array) {
+    CALL_GL_API_RETURN(glIsVertexArrayOES, array);
+}
 void API_ENTRY(glGetPerfMonitorGroupsAMD)(GLint *numGroups, GLsizei groupsSize, GLuint *groups) {
     CALL_GL_API(glGetPerfMonitorGroupsAMD, numGroups, groupsSize, groups);
 }
 void API_ENTRY(glGetPerfMonitorCountersAMD)(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) {
     CALL_GL_API(glGetPerfMonitorCountersAMD, group, numCounters, maxActiveCounters, counterSize, counters);
 }
-void API_ENTRY(glGetPerfMonitorGroupStringAMD)(GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) {
+void API_ENTRY(glGetPerfMonitorGroupStringAMD)(GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString) {
     CALL_GL_API(glGetPerfMonitorGroupStringAMD, group, bufSize, length, groupString);
 }
-void API_ENTRY(glGetPerfMonitorCounterStringAMD)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) {
+void API_ENTRY(glGetPerfMonitorCounterStringAMD)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString) {
     CALL_GL_API(glGetPerfMonitorCounterStringAMD, group, counter, bufSize, length, counterString);
 }
-void API_ENTRY(glGetPerfMonitorCounterInfoAMD)(GLuint group, GLuint counter, GLenum pname, void *data) {
+void API_ENTRY(glGetPerfMonitorCounterInfoAMD)(GLuint group, GLuint counter, GLenum pname, GLvoid *data) {
     CALL_GL_API(glGetPerfMonitorCounterInfoAMD, group, counter, pname, data);
 }
 void API_ENTRY(glGenPerfMonitorsAMD)(GLsizei n, GLuint *monitors) {
@@ -70,6 +82,21 @@
 void API_ENTRY(glGetPerfMonitorCounterDataAMD)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) {
     CALL_GL_API(glGetPerfMonitorCounterDataAMD, monitor, pname, dataSize, data, bytesWritten);
 }
+void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
+    CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
+}
+void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
+}
+void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
+}
+void API_ENTRY(glRenderbufferStorageMultisampleIMG)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+    CALL_GL_API(glRenderbufferStorageMultisampleIMG, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glFramebufferTexture2DMultisampleIMG)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+    CALL_GL_API(glFramebufferTexture2DMultisampleIMG, target, attachment, textarget, texture, level, samples);
+}
 void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) {
     CALL_GL_API(glDeleteFencesNV, n, fences);
 }
@@ -91,10 +118,16 @@
 void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) {
     CALL_GL_API(glSetFenceNV, fence, condition);
 }
+void API_ENTRY(glCoverageMaskNV)(GLboolean mask) {
+    CALL_GL_API(glCoverageMaskNV, mask);
+}
+void API_ENTRY(glCoverageOperationNV)(GLenum operation) {
+    CALL_GL_API(glCoverageOperationNV, operation);
+}
 void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) {
     CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls);
 }
-void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) {
+void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) {
     CALL_GL_API(glGetDriverControlStringQCOM, driverControl, bufSize, length, driverControlString);
 }
 void API_ENTRY(glEnableDriverControlQCOM)(GLuint driverControl) {
@@ -103,3 +136,45 @@
 void API_ENTRY(glDisableDriverControlQCOM)(GLuint driverControl) {
     CALL_GL_API(glDisableDriverControlQCOM, driverControl);
 }
+void API_ENTRY(glExtGetTexturesQCOM)(GLuint *textures, GLint maxTextures, GLint *numTextures) {
+    CALL_GL_API(glExtGetTexturesQCOM, textures, maxTextures, numTextures);
+}
+void API_ENTRY(glExtGetBuffersQCOM)(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) {
+    CALL_GL_API(glExtGetBuffersQCOM, buffers, maxBuffers, numBuffers);
+}
+void API_ENTRY(glExtGetRenderbuffersQCOM)(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) {
+    CALL_GL_API(glExtGetRenderbuffersQCOM, renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+void API_ENTRY(glExtGetFramebuffersQCOM)(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) {
+    CALL_GL_API(glExtGetFramebuffersQCOM, framebuffers, maxFramebuffers, numFramebuffers);
+}
+void API_ENTRY(glExtGetTexLevelParameterivQCOM)(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) {
+    CALL_GL_API(glExtGetTexLevelParameterivQCOM, texture, face, level, pname, params);
+}
+void API_ENTRY(glExtTexObjectStateOverrideiQCOM)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glExtTexObjectStateOverrideiQCOM, target, pname, param);
+}
+void API_ENTRY(glExtGetTexSubImageQCOM)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) {
+    CALL_GL_API(glExtGetTexSubImageQCOM, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+void API_ENTRY(glExtGetBufferPointervQCOM)(GLenum target, GLvoid **params) {
+    CALL_GL_API(glExtGetBufferPointervQCOM, target, params);
+}
+void API_ENTRY(glExtGetShadersQCOM)(GLuint *shaders, GLint maxShaders, GLint *numShaders) {
+    CALL_GL_API(glExtGetShadersQCOM, shaders, maxShaders, numShaders);
+}
+void API_ENTRY(glExtGetProgramsQCOM)(GLuint *programs, GLint maxPrograms, GLint *numPrograms) {
+    CALL_GL_API(glExtGetProgramsQCOM, programs, maxPrograms, numPrograms);
+}
+GLboolean API_ENTRY(glExtIsProgramBinaryQCOM)(GLuint program) {
+    CALL_GL_API_RETURN(glExtIsProgramBinaryQCOM, program);
+}
+void API_ENTRY(glExtGetProgramBinarySourceQCOM)(GLuint program, GLenum shadertype, GLchar *source, GLint *length) {
+    CALL_GL_API(glExtGetProgramBinarySourceQCOM, program, shadertype, source, length);
+}
+void API_ENTRY(glStartTilingQCOM)(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {
+    CALL_GL_API(glStartTilingQCOM, x, y, width, height, preserveMask);
+}
+void API_ENTRY(glEndTilingQCOM)(GLbitfield preserveMask) {
+    CALL_GL_API(glEndTilingQCOM, preserveMask);
+}
diff --git a/opengl/libs/GLES_CM/gl_api.in b/opengl/libs/GLES_CM/gl_api.in
index 5437d47..7f20c4f 100644
--- a/opengl/libs/GLES_CM/gl_api.in
+++ b/opengl/libs/GLES_CM/gl_api.in
@@ -259,7 +259,7 @@
 void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
     CALL_GL_API(glGetMaterialxv, face, pname, params);
 }
-void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
+void API_ENTRY(glGetPointerv)(GLenum pname, GLvoid **params) {
     CALL_GL_API(glGetPointerv, pname, params);
 }
 const GLubyte * API_ENTRY(glGetString)(GLenum name) {
diff --git a/opengl/libs/GLES_CM/glext_api.in b/opengl/libs/GLES_CM/glext_api.in
index 2c8648e..5393fa6 100644
--- a/opengl/libs/GLES_CM/glext_api.in
+++ b/opengl/libs/GLES_CM/glext_api.in
@@ -205,7 +205,7 @@
 GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
     CALL_GL_API_RETURN(glUnmapBufferOES, target);
 }
-void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) {
+void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, GLvoid ** params) {
     CALL_GL_API(glGetBufferPointervOES, target, pname, params);
 }
 void API_ENTRY(glCurrentPaletteMatrixOES)(GLuint matrixpaletteindex) {
@@ -268,3 +268,111 @@
 void API_ENTRY(glGetTexGenxvOES)(GLenum coord, GLenum pname, GLfixed *params) {
     CALL_GL_API(glGetTexGenxvOES, coord, pname, params);
 }
+void API_ENTRY(glBindVertexArrayOES)(GLuint array) {
+    CALL_GL_API(glBindVertexArrayOES, array);
+}
+void API_ENTRY(glDeleteVertexArraysOES)(GLsizei n, const GLuint *arrays) {
+    CALL_GL_API(glDeleteVertexArraysOES, n, arrays);
+}
+void API_ENTRY(glGenVertexArraysOES)(GLsizei n, GLuint *arrays) {
+    CALL_GL_API(glGenVertexArraysOES, n, arrays);
+}
+GLboolean API_ENTRY(glIsVertexArrayOES)(GLuint array) {
+    CALL_GL_API_RETURN(glIsVertexArrayOES, array);
+}
+void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
+    CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
+}
+void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
+}
+void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
+}
+void API_ENTRY(glClipPlanefIMG)(GLenum p, const GLfloat *eqn) {
+    CALL_GL_API(glClipPlanefIMG, p, eqn);
+}
+void API_ENTRY(glClipPlanexIMG)(GLenum p, const GLfixed *eqn) {
+    CALL_GL_API(glClipPlanexIMG, p, eqn);
+}
+void API_ENTRY(glRenderbufferStorageMultisampleIMG)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+    CALL_GL_API(glRenderbufferStorageMultisampleIMG, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glFramebufferTexture2DMultisampleIMG)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+    CALL_GL_API(glFramebufferTexture2DMultisampleIMG, target, attachment, textarget, texture, level, samples);
+}
+void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) {
+    CALL_GL_API(glDeleteFencesNV, n, fences);
+}
+void API_ENTRY(glGenFencesNV)(GLsizei n, GLuint *fences) {
+    CALL_GL_API(glGenFencesNV, n, fences);
+}
+GLboolean API_ENTRY(glIsFenceNV)(GLuint fence) {
+    CALL_GL_API_RETURN(glIsFenceNV, fence);
+}
+GLboolean API_ENTRY(glTestFenceNV)(GLuint fence) {
+    CALL_GL_API_RETURN(glTestFenceNV, fence);
+}
+void API_ENTRY(glGetFenceivNV)(GLuint fence, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetFenceivNV, fence, pname, params);
+}
+void API_ENTRY(glFinishFenceNV)(GLuint fence) {
+    CALL_GL_API(glFinishFenceNV, fence);
+}
+void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) {
+    CALL_GL_API(glSetFenceNV, fence, condition);
+}
+void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) {
+    CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls);
+}
+void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) {
+    CALL_GL_API(glGetDriverControlStringQCOM, driverControl, bufSize, length, driverControlString);
+}
+void API_ENTRY(glEnableDriverControlQCOM)(GLuint driverControl) {
+    CALL_GL_API(glEnableDriverControlQCOM, driverControl);
+}
+void API_ENTRY(glDisableDriverControlQCOM)(GLuint driverControl) {
+    CALL_GL_API(glDisableDriverControlQCOM, driverControl);
+}
+void API_ENTRY(glExtGetTexturesQCOM)(GLuint *textures, GLint maxTextures, GLint *numTextures) {
+    CALL_GL_API(glExtGetTexturesQCOM, textures, maxTextures, numTextures);
+}
+void API_ENTRY(glExtGetBuffersQCOM)(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) {
+    CALL_GL_API(glExtGetBuffersQCOM, buffers, maxBuffers, numBuffers);
+}
+void API_ENTRY(glExtGetRenderbuffersQCOM)(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) {
+    CALL_GL_API(glExtGetRenderbuffersQCOM, renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+void API_ENTRY(glExtGetFramebuffersQCOM)(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) {
+    CALL_GL_API(glExtGetFramebuffersQCOM, framebuffers, maxFramebuffers, numFramebuffers);
+}
+void API_ENTRY(glExtGetTexLevelParameterivQCOM)(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) {
+    CALL_GL_API(glExtGetTexLevelParameterivQCOM, texture, face, level, pname, params);
+}
+void API_ENTRY(glExtTexObjectStateOverrideiQCOM)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glExtTexObjectStateOverrideiQCOM, target, pname, param);
+}
+void API_ENTRY(glExtGetTexSubImageQCOM)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) {
+    CALL_GL_API(glExtGetTexSubImageQCOM, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+void API_ENTRY(glExtGetBufferPointervQCOM)(GLenum target, GLvoid **params) {
+    CALL_GL_API(glExtGetBufferPointervQCOM, target, params);
+}
+void API_ENTRY(glExtGetShadersQCOM)(GLuint *shaders, GLint maxShaders, GLint *numShaders) {
+    CALL_GL_API(glExtGetShadersQCOM, shaders, maxShaders, numShaders);
+}
+void API_ENTRY(glExtGetProgramsQCOM)(GLuint *programs, GLint maxPrograms, GLint *numPrograms) {
+    CALL_GL_API(glExtGetProgramsQCOM, programs, maxPrograms, numPrograms);
+}
+GLboolean API_ENTRY(glExtIsProgramBinaryQCOM)(GLuint program) {
+    CALL_GL_API_RETURN(glExtIsProgramBinaryQCOM, program);
+}
+void API_ENTRY(glExtGetProgramBinarySourceQCOM)(GLuint program, GLenum shadertype, GLchar *source, GLint *length) {
+    CALL_GL_API(glExtGetProgramBinarySourceQCOM, program, shadertype, source, length);
+}
+void API_ENTRY(glStartTilingQCOM)(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {
+    CALL_GL_API(glStartTilingQCOM, x, y, width, height, preserveMask);
+}
+void API_ENTRY(glEndTilingQCOM)(GLbitfield preserveMask) {
+    CALL_GL_API(glEndTilingQCOM, preserveMask);
+}
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 1fba209..c8f529a 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -31,6 +31,7 @@
 
 struct egl_connection_t
 {
+    inline egl_connection_t() : dso(0) { }
     void *              dso;
     gl_hooks_t *        hooks[2];
     EGLint              major;
diff --git a/opengl/libs/entries.in b/opengl/libs/entries.in
index bbe3e23..61acb5f 100644
--- a/opengl/libs/entries.in
+++ b/opengl/libs/entries.in
@@ -4,13 +4,14 @@
 GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref)
 GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
 GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
-GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const char* name)
+GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name)
 GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
 GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
 GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
 GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
 GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
 GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
+GL_ENTRY(void, glBindVertexArrayOES, GLuint array)
 GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
 GL_ENTRY(void, glBlendEquation,  GLenum mode )
 GL_ENTRY(void, glBlendEquationOES, GLenum mode)
@@ -34,8 +35,10 @@
 GL_ENTRY(void, glClearStencil, GLint s)
 GL_ENTRY(void, glClientActiveTexture, GLenum texture)
 GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation)
+GL_ENTRY(void, glClipPlanefIMG, GLenum p, const GLfloat *eqn)
 GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation)
 GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation)
+GL_ENTRY(void, glClipPlanexIMG, GLenum p, const GLfixed *eqn)
 GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation)
 GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
@@ -45,12 +48,14 @@
 GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
 GL_ENTRY(void, glCompileShader, GLuint shader)
 GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
-GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
 GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
-GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
 GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
 GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
 GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glCoverageMaskNV, GLboolean mask)
+GL_ENTRY(void, glCoverageOperationNV, GLenum operation)
 GL_ENTRY(GLuint, glCreateProgram, void)
 GL_ENTRY(GLuint, glCreateShader, GLenum type)
 GL_ENTRY(void, glCullFace, GLenum mode)
@@ -65,6 +70,7 @@
 GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers)
 GL_ENTRY(void, glDeleteShader, GLuint shader)
 GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures)
+GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays)
 GL_ENTRY(void, glDepthFunc, GLenum func)
 GL_ENTRY(void, glDepthMask, GLboolean flag)
 GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
@@ -76,6 +82,7 @@
 GL_ENTRY(void, glDisableClientState, GLenum array)
 GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl)
 GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
+GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments)
 GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
 GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
 GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
@@ -93,6 +100,19 @@
 GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl)
 GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
 GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask)
+GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoid **params)
+GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
+GL_ENTRY(void, glExtGetFramebuffersQCOM, GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers)
+GL_ENTRY(void, glExtGetProgramBinarySourceQCOM, GLuint program, GLenum shadertype, GLchar *source, GLint *length)
+GL_ENTRY(void, glExtGetProgramsQCOM, GLuint *programs, GLint maxPrograms, GLint *numPrograms)
+GL_ENTRY(void, glExtGetRenderbuffersQCOM, GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers)
+GL_ENTRY(void, glExtGetShadersQCOM, GLuint *shaders, GLint maxShaders, GLint *numShaders)
+GL_ENTRY(void, glExtGetTexLevelParameterivQCOM, GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params)
+GL_ENTRY(void, glExtGetTexSubImageQCOM, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels)
+GL_ENTRY(void, glExtGetTexturesQCOM, GLuint *textures, GLint maxTextures, GLint *numTextures)
+GL_ENTRY(GLboolean, glExtIsProgramBinaryQCOM, GLuint program)
+GL_ENTRY(void, glExtTexObjectStateOverrideiQCOM, GLenum target, GLenum pname, GLint param)
 GL_ENTRY(void, glFinish, void)
 GL_ENTRY(void, glFinishFenceNV, GLuint fence)
 GL_ENTRY(void, glFlush, void)
@@ -105,6 +125,7 @@
 GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
 GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
 GL_ENTRY(void, glFrontFace, GLenum mode)
@@ -120,20 +141,21 @@
 GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers)
 GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers)
 GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
+GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays)
 GL_ENTRY(void, glGenerateMipmap, GLenum target)
 GL_ENTRY(void, glGenerateMipmapOES, GLenum target)
-GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
-GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
 GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-GL_ENTRY(int, glGetAttribLocation, GLuint program, const char* name)
+GL_ENTRY(int, glGetAttribLocation, GLuint program, const GLchar* name)
 GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params)
 GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params)
+GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, GLvoid ** params)
 GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4])
 GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4])
 GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4])
 GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4])
-GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString)
+GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)
 GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls)
 GL_ENTRY(GLenum, glGetError, void)
 GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params)
@@ -150,20 +172,20 @@
 GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params)
 GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params)
 GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten)
-GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, void *data)
-GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString)
+GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, GLvoid *data)
+GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString)
 GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters)
-GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, char *groupString)
+GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString)
 GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups)
-GL_ENTRY(void, glGetPointerv, GLenum pname, void **params)
-GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
-GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+GL_ENTRY(void, glGetPointerv, GLenum pname, GLvoid **params)
+GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
+GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
 GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params)
 GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params)
 GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
 GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
 GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params)
 GL_ENTRY(const GLubyte *, glGetString, GLenum name)
 GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params)
@@ -177,10 +199,10 @@
 GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params)
 GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params)
 GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params)
-GL_ENTRY(int, glGetUniformLocation, GLuint program, const char* name)
+GL_ENTRY(int, glGetUniformLocation, GLuint program, const GLchar* name)
 GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params)
 GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params)
-GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer)
+GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
 GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params)
 GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params)
 GL_ENTRY(void, glHint, GLenum target, GLenum mode)
@@ -194,6 +216,7 @@
 GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer)
 GL_ENTRY(GLboolean, glIsShader, GLuint shader)
 GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
+GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array)
 GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param)
 GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params)
 GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param)
@@ -228,6 +251,8 @@
 GL_ENTRY(void, glMultMatrixf, const GLfloat *m)
 GL_ENTRY(void, glMultMatrixx, const GLfixed *m)
 GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m)
+GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
+GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount)
 GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
 GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
 GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
@@ -254,12 +279,13 @@
 GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
 GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units)
 GL_ENTRY(void, glPopMatrix, void)
-GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
 GL_ENTRY(void, glPushMatrix, void)
 GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16])
 GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
 GL_ENTRY(void, glReleaseShaderCompiler, void)
 GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
 GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
 GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
 GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
@@ -274,8 +300,9 @@
 GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList)
 GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition)
 GL_ENTRY(void, glShadeModel, GLenum mode)
-GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
-GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const char** string, const GLint* length)
+GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
+GL_ENTRY(void, glStartTilingQCOM, GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
 GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
 GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
 GL_ENTRY(void, glStencilMask, GLuint mask)
@@ -298,8 +325,8 @@
 GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params)
 GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param)
 GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
 GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
 GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params)
 GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
@@ -309,7 +336,7 @@
 GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params)
 GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params)
 GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
-GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
 GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z)
 GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z)
 GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z)
@@ -343,7 +370,7 @@
 GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values)
 GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values)
-GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
 GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
 GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
 GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index f47f093..1ab58cc 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -37,7 +37,7 @@
 #endif
 #undef NELEM
 #define NELEM(x)                    (sizeof(x)/sizeof(*(x)))
-#define MAX_NUMBER_OF_GL_EXTENSIONS 32
+#define MAX_NUMBER_OF_GL_EXTENSIONS 64
 
 
 #if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
@@ -86,7 +86,7 @@
         #include "entries.in"
     } gl;
     struct gl_ext_t {
-        void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
+        __eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];
     } ext;
 };
 #undef GL_ENTRY
diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp
index 06fa0c2..4d10ee5 100644
--- a/opengl/tests/angeles/app-linux.cpp
+++ b/opengl/tests/angeles/app-linux.cpp
@@ -63,7 +63,7 @@
 int gAppAlive = 1;
 
 static const char sAppName[] =
-    "San Angeles Observation OpenGL ES version example (Linux)";
+        "San Angeles Observation OpenGL ES version example (Linux)";
 
 static int sWindowWidth = WINDOW_DEFAULT_WIDTH;
 static int sWindowHeight = WINDOW_DEFAULT_HEIGHT;
@@ -74,22 +74,22 @@
 const char *egl_strerror(unsigned err)
 {
     switch(err){
-    case EGL_SUCCESS: return "SUCCESS";
-    case EGL_NOT_INITIALIZED: return "NOT INITIALIZED";
-    case EGL_BAD_ACCESS: return "BAD ACCESS";
-    case EGL_BAD_ALLOC: return "BAD ALLOC";
-    case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE";
-    case EGL_BAD_CONFIG: return "BAD CONFIG";
-    case EGL_BAD_CONTEXT: return "BAD CONTEXT";
-    case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE";
-    case EGL_BAD_DISPLAY: return "BAD DISPLAY";
-    case EGL_BAD_MATCH: return "BAD MATCH";
-    case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP";
-    case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW";
-    case EGL_BAD_PARAMETER: return "BAD PARAMETER";
-    case EGL_BAD_SURFACE: return "BAD_SURFACE";
-//    case EGL_CONTEXT_LOST: return "CONTEXT LOST";
-    default: return "UNKNOWN";
+        case EGL_SUCCESS: return "SUCCESS";
+        case EGL_NOT_INITIALIZED: return "NOT INITIALIZED";
+        case EGL_BAD_ACCESS: return "BAD ACCESS";
+        case EGL_BAD_ALLOC: return "BAD ALLOC";
+        case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG: return "BAD CONFIG";
+        case EGL_BAD_CONTEXT: return "BAD CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE";
+        case EGL_BAD_DISPLAY: return "BAD DISPLAY";
+        case EGL_BAD_MATCH: return "BAD MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW";
+        case EGL_BAD_PARAMETER: return "BAD PARAMETER";
+        case EGL_BAD_SURFACE: return "BAD_SURFACE";
+        //    case EGL_CONTEXT_LOST: return "CONTEXT LOST";
+        default: return "UNKNOWN";
     }
 }
 
@@ -118,52 +118,59 @@
         fprintf(stderr, "EGL Error: 0x%04x\n", (int)error);
 }
 
-static int initGraphics()
+static int initGraphics(unsigned samples)
 {
     EGLint configAttribs[] = {
-         EGL_DEPTH_SIZE, 16,
-         EGL_NONE
-     };
-     
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLContext context;
-     EGLConfig config;
-     EGLSurface surface;
-     EGLint w, h;
-     EGLDisplay dpy;
+            EGL_DEPTH_SIZE, 16,
+            EGL_SAMPLE_BUFFERS, samples ? 1 : 0,
+                    EGL_SAMPLES, samples,
+                    EGL_NONE
+    };
 
-     EGLNativeWindowType window = android_createDisplaySurface();
-     
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     eglInitialize(dpy, &majorVersion, &minorVersion);
-          
-     status_t err = EGLUtils::selectConfigForNativeWindow(
-             dpy, configAttribs, window, &config);
-     if (err) {
-         fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
-         return 0;
-     }
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLint w, h;
+    EGLDisplay dpy;
 
-     surface = eglCreateWindowSurface(dpy, config, window, NULL);
-     egl_error("eglCreateWindowSurface");
+    EGLNativeWindowType window = android_createDisplaySurface();
 
-     fprintf(stderr,"surface = %p\n", surface);
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(dpy, &majorVersion, &minorVersion);
 
-     context = eglCreateContext(dpy, config, NULL, NULL);
-     egl_error("eglCreateContext");
-     fprintf(stderr,"context = %p\n", context);
-     
-     eglMakeCurrent(dpy, surface, surface, context);   
-     egl_error("eglMakeCurrent");
+    status_t err = EGLUtils::selectConfigForNativeWindow(
+            dpy, configAttribs, window, &config);
+    if (err) {
+        fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
+        return 0;
+    }
 
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth);
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight);
+    surface = eglCreateWindowSurface(dpy, config, window, NULL);
+    egl_error("eglCreateWindowSurface");
+
+    fprintf(stderr,"surface = %p\n", surface);
+
+    context = eglCreateContext(dpy, config, NULL, NULL);
+    egl_error("eglCreateContext");
+    fprintf(stderr,"context = %p\n", context);
+
+    eglMakeCurrent(dpy, surface, surface, context);
+    egl_error("eglMakeCurrent");
+
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth);
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight);
 
     sEglDisplay = dpy;
     sEglSurface = surface;
     sEglContext = context;
 
+    if (samples == 0) {
+        // GL_MULTISAMPLE is enabled by default
+        glDisable(GL_MULTISAMPLE);
+    }
+
     return EGL_TRUE;
 }
 
@@ -179,35 +186,47 @@
 
 int main(int argc, char *argv[])
 {
-    // not referenced:
-    argc = argc;
-    argv = argv;
+    unsigned samples = 0;
+    printf("usage: %s [samples]\n", argv[0]);
+    if (argc == 2) {
+        samples = atoi( argv[1] );
+        printf("Multisample enabled: GL_SAMPLES = %u\n", samples);
+    }
 
-    if (!initGraphics())
+    if (!initGraphics(samples))
     {
         fprintf(stderr, "Graphics initialization failed.\n");
         return EXIT_FAILURE;
     }
 
     appInit();
-    
+
+    struct timeval timeTemp;
+    int frameCount = 0;
+    gettimeofday(&timeTemp, NULL);
+    double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec;
+
     while (gAppAlive)
     {
         struct timeval timeNow;
 
-        if (gAppAlive)
-        {
-            gettimeofday(&timeNow, NULL);
-            appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000,
-                      sWindowWidth, sWindowHeight);
-            checkGLErrors();
-            eglSwapBuffers(sEglDisplay, sEglSurface);
-            checkEGLErrors();
-        }
+        gettimeofday(&timeNow, NULL);
+        appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000,
+                sWindowWidth, sWindowHeight);
+        checkGLErrors();
+        eglSwapBuffers(sEglDisplay, sEglSurface);
+        checkEGLErrors();
+        frameCount++;
     }
 
+    gettimeofday(&timeTemp, NULL);
+
     appDeinit();
     deinitGraphics();
 
+    totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime;
+    printf("totalTime=%f s, frameCount=%d, %.2f fps\n",
+            totalTime, frameCount, frameCount/totalTime);
+
     return EXIT_SUCCESS;
 }
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 2361db5..f274c7c 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -195,7 +195,6 @@
     X(EGL_NATIVE_RENDERABLE),
     X(EGL_NATIVE_VISUAL_ID),
     X(EGL_NATIVE_VISUAL_TYPE),
-    X(EGL_PRESERVED_RESOURCES),
     X(EGL_SAMPLES),
     X(EGL_SAMPLE_BUFFERS),
     X(EGL_SURFACE_TYPE),
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index feb964a..0cc8398 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -114,7 +114,6 @@
     X(EGL_NATIVE_RENDERABLE),
     X(EGL_NATIVE_VISUAL_ID),
     X(EGL_NATIVE_VISUAL_TYPE),
-    X(EGL_PRESERVED_RESOURCES),
     X(EGL_SAMPLES),
     X(EGL_SAMPLE_BUFFERS),
     X(EGL_SURFACE_TYPE),
diff --git a/opengl/tools/glgen/specs/gles11/GLES20.spec b/opengl/tools/glgen/specs/gles11/GLES20.spec
index 61094d1..ee88f59 100644
--- a/opengl/tools/glgen/specs/gles11/GLES20.spec
+++ b/opengl/tools/glgen/specs/gles11/GLES20.spec
@@ -39,6 +39,7 @@
 void glDisable ( GLenum cap )
 void glDisableVertexAttribArray ( GLuint index )
 void glDrawArrays ( GLenum mode, GLint first, GLsizei count )
+void glDrawElements ( GLenum mode, GLsizei count, GLenum type, GLint offset )
 void glDrawElements ( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices )
 void glEnable ( GLenum cap )
 void glEnableVertexAttribArray ( GLuint index )
@@ -138,5 +139,6 @@
 void glVertexAttrib3fv ( GLuint indx, const GLfloat *values )
 void glVertexAttrib4f ( GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w )
 void glVertexAttrib4fv ( GLuint indx, const GLfloat *values )
+void glVertexAttribPointer ( GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLint offset )
 void glVertexAttribPointer ( GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *ptr )
-void glViewport ( GLint x, GLint y, GLsizei width, GLsizei height )
\ No newline at end of file
+void glViewport ( GLint x, GLint y, GLsizei width, GLsizei height )
diff --git a/opengl/tools/glgen/src/JniCodeEmitter.java b/opengl/tools/glgen/src/JniCodeEmitter.java
index ebaca90..9d8c5a0 100644
--- a/opengl/tools/glgen/src/JniCodeEmitter.java
+++ b/opengl/tools/glgen/src/JniCodeEmitter.java
@@ -695,7 +695,7 @@
         boolean isPointerFunc = isPointerFunc(jfunc);
         boolean isVBOPointerFunc = (outName.endsWith("Pointer") ||
                 outName.endsWith("PointerOES") ||
-            outName.endsWith("DrawElements")) &&
+            outName.endsWith("DrawElements") || outName.endsWith("VertexAttribPointer")) &&
             !jfunc.getCFunc().hasPointerArg();
         if (isPointerFunc) {
             outName += "Bounds";
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 86eb78d..a14bfb5 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -6,6 +6,7 @@
     DisplayHardware/DisplayHardware.cpp \
     DisplayHardware/DisplayHardwareBase.cpp \
     BlurFilter.cpp.arm \
+    GLExtensions.cpp \
     Layer.cpp \
     LayerBase.cpp \
     LayerBuffer.cpp \
@@ -13,14 +14,14 @@
     LayerDim.cpp \
     MessageQueue.cpp \
     SurfaceFlinger.cpp \
-    Tokenizer.cpp \
+    TextureManager.cpp \
     Transform.cpp
 
 LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
 LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
 
-ifeq ($(TARGET_BOARD_PLATFORM), msm7k)
-	LOCAL_CFLAGS += -DDIM_WITH_TEXTURE
+ifeq ($(TARGET_BOARD_PLATFORM), omap3)
+	LOCAL_CFLAGS += -DNO_RGBX_8888
 endif
 
 # need "-lrt" on Linux simulator to pick up clock_gettime
diff --git a/services/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h
index e2bcf6a..6f8507e 100644
--- a/services/surfaceflinger/Barrier.h
+++ b/services/surfaceflinger/Barrier.h
@@ -29,10 +29,6 @@
     inline Barrier() : state(CLOSED) { }
     inline ~Barrier() { }
     void open() {
-        // gcc memory barrier, this makes sure all memory writes
-        // have been issued by gcc. On an SMP system we'd need a real
-        // h/w barrier.
-        asm volatile ("":::"memory");
         Mutex::Autolock _l(lock);
         state = OPENED;
         cv.broadcast();
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
index ea68352..2eac0a8 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -40,6 +40,8 @@
 #include <hardware/overlay.h>
 #include <hardware/gralloc.h>
 
+#include "GLExtensions.h"
+
 using namespace android;
 
 
@@ -73,7 +75,8 @@
 DisplayHardware::DisplayHardware(
         const sp<SurfaceFlinger>& flinger,
         uint32_t dpy)
-    : DisplayHardwareBase(flinger, dpy)
+    : DisplayHardwareBase(flinger, dpy),
+      mFlags(0)
 {
     init(dpy);
 }
@@ -97,6 +100,9 @@
 {
     mNativeWindow = new FramebufferNativeWindow();
     framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
+    mDpiX = mNativeWindow->xdpi;
+    mDpiY = mNativeWindow->ydpi;
+    mRefreshRate = fbDev->fps;
 
     mOverlayEngine = NULL;
     hw_module_t const* module;
@@ -104,6 +110,11 @@
         overlay_control_open(module, &mOverlayEngine);
     }
 
+    EGLint w, h, dummy;
+    EGLint numConfigs=0;
+    EGLSurface surface;
+    EGLContext context;
+
     // initialize EGL
     EGLint attribs[] = {
             EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
@@ -121,12 +132,6 @@
         }
     }
 
-    EGLint w, h, dummy;
-    EGLint numConfigs=0;
-    EGLSurface surface;
-    EGLContext context;
-    mFlags = CACHED_BUFFERS;
-
     // TODO: all the extensions below should be queried through
     // eglGetProcAddress().
 
@@ -145,22 +150,6 @@
     eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
     eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
 
-    /*
-     * Gather EGL extensions
-     */
-
-    const char* const egl_extensions = eglQueryString(
-            display, EGL_EXTENSIONS);
-    
-    LOGI("EGL informations:");
-    LOGI("# of configs : %d", numConfigs);
-    LOGI("vendor    : %s", eglQueryString(display, EGL_VENDOR));
-    LOGI("version   : %s", eglQueryString(display, EGL_VERSION));
-    LOGI("extensions: %s", egl_extensions);
-    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
-    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
-    
-
     if (mNativeWindow->isUpdateOnDemand()) {
         mFlags |= PARTIAL_UPDATES;
     }
@@ -175,6 +164,8 @@
      */
 
     surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
+    eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth);
+    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
 
     if (mFlags & PARTIAL_UPDATES) {
         // if we have partial updates, we definitely don't need to
@@ -188,31 +179,6 @@
             mFlags |= BUFFER_PRESERVED;
         }
     }
-
-    eglQuerySurface(display, surface, EGL_WIDTH,  &mWidth);
-    eglQuerySurface(display, surface, EGL_HEIGHT, &mHeight);
-
-#ifdef EGL_ANDROID_swap_rectangle    
-    if (strstr(egl_extensions, "EGL_ANDROID_swap_rectangle")) {
-        if (eglSetSwapRectangleANDROID(display, surface,
-                0, 0, mWidth, mHeight) == EGL_TRUE) {
-            // This could fail if this extension is not supported by this
-            // specific surface (of config)
-            mFlags |= SWAP_RECTANGLE;
-        }
-    }
-    // when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE
-    // choose PARTIAL_UPDATES, which should be more efficient
-    if (mFlags & PARTIAL_UPDATES)
-        mFlags &= ~SWAP_RECTANGLE;
-#endif
-    
-
-    LOGI("flags     : %08x", mFlags);
-    
-    mDpiX = mNativeWindow->xdpi;
-    mDpiY = mNativeWindow->ydpi;
-    mRefreshRate = fbDev->fps; 
     
     /* Read density from build-specific ro.sf.lcd_density property
      * except if it is overridden by qemu.sf.lcd_density.
@@ -235,61 +201,67 @@
     
     context = eglCreateContext(display, config, NULL, NULL);
     
-    /*
-     * Gather OpenGL ES extensions
-     */
-
-    eglMakeCurrent(display, surface, surface, context);
-    const char* const  gl_extensions = (const char*)glGetString(GL_EXTENSIONS);
-    const char* const  gl_renderer = (const char*)glGetString(GL_RENDERER);
-    LOGI("OpenGL informations:");
-    LOGI("vendor    : %s", glGetString(GL_VENDOR));
-    LOGI("renderer  : %s", gl_renderer);
-    LOGI("version   : %s", glGetString(GL_VERSION));
-    LOGI("extensions: %s", gl_extensions);
-
-    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
-    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims);
-    LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
-    LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims);
-
-#if 0
-    // for drivers that don't have proper support for flushing cached buffers
-    // on gralloc unlock, uncomment this block and test for the specific
-    // renderer substring
-    if (strstr(gl_renderer, "<some vendor string>")) {
-        LOGD("Assuming uncached graphics buffers.");
-        mFlags &= ~CACHED_BUFFERS;
-    }
-#endif
-
-    if (strstr(gl_extensions, "GL_ARB_texture_non_power_of_two")) {
-        mFlags |= NPOT_EXTENSION;
-    }
-    if (strstr(gl_extensions, "GL_OES_draw_texture")) {
-        mFlags |= DRAW_TEXTURE_EXTENSION;
-    }
-#ifdef EGL_ANDROID_image_native_buffer
-    if (strstr( gl_extensions, "GL_OES_EGL_image") &&
-        (strstr(egl_extensions, "EGL_KHR_image_base") || 
-                strstr(egl_extensions, "EGL_KHR_image")) &&
-        strstr(egl_extensions, "EGL_ANDROID_image_native_buffer")) {
-        mFlags |= DIRECT_TEXTURE;
-    }
-#else
-#warning "EGL_ANDROID_image_native_buffer not supported"
-#endif
-
-
-    // Unbind the context from this thread
-    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
     mDisplay = display;
     mConfig  = config;
     mSurface = surface;
     mContext = context;
     mFormat  = fbDev->format;
     mPageFlipCount = 0;
+
+    /*
+     * Gather OpenGL ES extensions
+     */
+
+    eglMakeCurrent(display, surface, surface, context);
+
+    GLExtensions& extensions(GLExtensions::getInstance());
+    extensions.initWithGLStrings(
+            glGetString(GL_VENDOR),
+            glGetString(GL_RENDERER),
+            glGetString(GL_VERSION),
+            glGetString(GL_EXTENSIONS),
+            eglQueryString(display, EGL_VENDOR),
+            eglQueryString(display, EGL_VERSION),
+            eglQueryString(display, EGL_EXTENSIONS));
+
+    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
+    glGetIntegerv(GL_MAX_VIEWPORT_DIMS, &mMaxViewportDims);
+
+
+#ifdef EGL_ANDROID_swap_rectangle
+    if (extensions.hasExtension("EGL_ANDROID_swap_rectangle")) {
+        if (eglSetSwapRectangleANDROID(display, surface,
+                0, 0, mWidth, mHeight) == EGL_TRUE) {
+            // This could fail if this extension is not supported by this
+            // specific surface (of config)
+            mFlags |= SWAP_RECTANGLE;
+        }
+    }
+    // when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE
+    // choose PARTIAL_UPDATES, which should be more efficient
+    if (mFlags & PARTIAL_UPDATES)
+        mFlags &= ~SWAP_RECTANGLE;
+#endif
+
+    LOGI("EGL informations:");
+    LOGI("# of configs : %d", numConfigs);
+    LOGI("vendor    : %s", extensions.getEglVendor());
+    LOGI("version   : %s", extensions.getEglVersion());
+    LOGI("extensions: %s", extensions.getEglExtension());
+    LOGI("Client API: %s", eglQueryString(display, EGL_CLIENT_APIS)?:"Not Supported");
+    LOGI("EGLSurface: %d-%d-%d-%d, config=%p", r, g, b, a, config);
+
+    LOGI("OpenGL informations:");
+    LOGI("vendor    : %s", extensions.getVendor());
+    LOGI("renderer  : %s", extensions.getRenderer());
+    LOGI("version   : %s", extensions.getVersion());
+    LOGI("extensions: %s", extensions.getExtension());
+    LOGI("GL_MAX_TEXTURE_SIZE = %d", mMaxTextureSize);
+    LOGI("GL_MAX_VIEWPORT_DIMS = %d", mMaxViewportDims);
+    LOGI("flags = %08x", mFlags);
+
+    // Unbind the context from this thread
+    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
 }
 
 /*
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
index df046af..66bf521 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -29,6 +29,8 @@
 
 #include <pixelflinger/pixelflinger.h>
 
+#include "GLExtensions.h"
+
 #include "DisplayHardware/DisplayHardwareBase.h"
 
 struct overlay_control_device_t;
@@ -43,15 +45,11 @@
 {
 public:
     enum {
-        DIRECT_TEXTURE          = 0x00000002,
-        COPY_BITS_EXTENSION     = 0x00000008,
-        NPOT_EXTENSION          = 0x00000100,
-        DRAW_TEXTURE_EXTENSION  = 0x00000200,
-        BUFFER_PRESERVED        = 0x00010000,
-        PARTIAL_UPDATES         = 0x00020000,   // video driver feature
-        SLOW_CONFIG             = 0x00040000,   // software
-        SWAP_RECTANGLE          = 0x00080000,
-        CACHED_BUFFERS          = 0x00100000
+        COPY_BITS_EXTENSION         = 0x00000008,
+        BUFFER_PRESERVED            = 0x00010000,
+        PARTIAL_UPDATES             = 0x00020000,   // video driver feature
+        SLOW_CONFIG                 = 0x00040000,   // software
+        SWAP_RECTANGLE              = 0x00080000,
     };
 
     DisplayHardware(
diff --git a/services/surfaceflinger/GLExtensions.cpp b/services/surfaceflinger/GLExtensions.cpp
new file mode 100644
index 0000000..7f4f9fc
--- /dev/null
+++ b/services/surfaceflinger/GLExtensions.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "GLExtensions.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE( GLExtensions )
+
+GLExtensions::GLExtensions()
+    : mHaveTextureExternal(false),
+      mHaveNpot(false),
+      mHaveDirectTexture(false)
+{
+}
+
+void GLExtensions::initWithGLStrings(
+        GLubyte const* vendor,
+        GLubyte const* renderer,
+        GLubyte const* version,
+        GLubyte const* extensions,
+        char const* egl_vendor,
+        char const* egl_version,
+        char const* egl_extensions)
+{
+    mVendor     = (char const*)vendor;
+    mRenderer   = (char const*)renderer;
+    mVersion    = (char const*)version;
+    mExtensions = (char const*)extensions;
+    mEglVendor     = egl_vendor;
+    mEglVersion    = egl_version;
+    mEglExtensions = egl_extensions;
+
+    char const* curr = (char const*)extensions;
+    char const* head = curr;
+    do {
+        head = strchr(curr, ' ');
+        String8 s(curr, head ? head-curr : strlen(curr));
+        if (s.length()) {
+            mExtensionList.add(s);
+        }
+        curr = head+1;
+    } while (head);
+
+    curr = egl_extensions;
+    head = curr;
+    do {
+        head = strchr(curr, ' ');
+        String8 s(curr, head ? head-curr : strlen(curr));
+        if (s.length()) {
+            mExtensionList.add(s);
+        }
+        curr = head+1;
+    } while (head);
+
+#ifdef EGL_ANDROID_image_native_buffer
+    if (hasExtension("GL_OES_EGL_image") &&
+        (hasExtension("EGL_KHR_image_base") || hasExtension("EGL_KHR_image")) &&
+        hasExtension("EGL_ANDROID_image_native_buffer"))
+    {
+        mHaveDirectTexture = true;
+    }
+#else
+#warning "EGL_ANDROID_image_native_buffer not supported"
+#endif
+
+    if (hasExtension("GL_ARB_texture_non_power_of_two")) {
+        mHaveNpot = true;
+    }
+
+    if (hasExtension("GL_OES_texture_external")) {
+        mHaveTextureExternal = true;
+    } else if (strstr(mRenderer.string(), "Adreno")) {
+        // hack for Adreno 200
+        mHaveTextureExternal = true;
+    }
+}
+
+bool GLExtensions::hasExtension(char const* extension) const
+{
+    const String8 s(extension);
+    return mExtensionList.indexOf(s) >= 0;
+}
+
+char const* GLExtensions::getVendor() const {
+    return mVendor.string();
+}
+
+char const* GLExtensions::getRenderer() const {
+    return mRenderer.string();
+}
+
+char const* GLExtensions::getVersion() const {
+    return mVersion.string();
+}
+
+char const* GLExtensions::getExtension() const {
+    return mExtensions.string();
+}
+
+char const* GLExtensions::getEglVendor() const {
+    return mEglVendor.string();
+}
+
+char const* GLExtensions::getEglVersion() const {
+    return mEglVersion.string();
+}
+
+char const* GLExtensions::getEglExtension() const {
+    return mEglExtensions.string();
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/GLExtensions.h b/services/surfaceflinger/GLExtensions.h
new file mode 100644
index 0000000..bbb284e
--- /dev/null
+++ b/services/surfaceflinger/GLExtensions.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_SF_GLEXTENSION_H
+#define ANDROID_SF_GLEXTENSION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/String8.h>
+#include <utils/SortedVector.h>
+#include <utils/Singleton.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class GLExtensions : public Singleton<GLExtensions>
+{
+    friend class Singleton<GLExtensions>;
+
+    bool mHaveTextureExternal   : 1;
+    bool mHaveNpot              : 1;
+    bool mHaveDirectTexture     : 1;
+
+    String8 mVendor;
+    String8 mRenderer;
+    String8 mVersion;
+    String8 mExtensions;
+    String8 mEglVendor;
+    String8 mEglVersion;
+    String8 mEglExtensions;
+    SortedVector<String8> mExtensionList;
+
+    GLExtensions(const GLExtensions&);
+    GLExtensions& operator = (const GLExtensions&);
+
+protected:
+    GLExtensions();
+
+public:
+    inline bool haveTextureExternal() const {
+        return mHaveTextureExternal;
+    }
+    inline bool haveNpot() const {
+        return mHaveNpot;
+    }
+    inline bool haveDirectTexture() const {
+        return mHaveDirectTexture;
+    }
+
+    void initWithGLStrings(
+            GLubyte const* vendor,
+            GLubyte const* renderer,
+            GLubyte const* version,
+            GLubyte const* extensions,
+            char const* egl_vendor,
+            char const* egl_version,
+            char const* egl_extensions);
+
+    char const* getVendor() const;
+    char const* getRenderer() const;
+    char const* getVersion() const;
+    char const* getExtension() const;
+
+    char const* getEglVendor() const;
+    char const* getEglVersion() const;
+    char const* getEglExtension() const;
+
+    bool hasExtension(char const* extension) const;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SF_GLEXTENSION_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ce7e9aa..695cbfa 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -31,6 +31,7 @@
 #include <surfaceflinger/Surface.h>
 
 #include "clz.h"
+#include "GLExtensions.h"
 #include "Layer.h"
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
@@ -47,47 +48,73 @@
 
 // ---------------------------------------------------------------------------
 
-const uint32_t Layer::typeInfo = LayerBaseClient::typeInfo | 4;
-const char* const Layer::typeID = "Layer";
-
-// ---------------------------------------------------------------------------
-
-Layer::Layer(SurfaceFlinger* flinger, DisplayID display, 
-        const sp<Client>& c, int32_t i)
-    :   LayerBaseClient(flinger, display, c, i),
-        mSecure(false),
-        mNoEGLImageForSwBuffers(false),
+Layer::Layer(SurfaceFlinger* flinger,
+        DisplayID display, const sp<Client>& client)
+    :   LayerBaseClient(flinger, display, client),
+        mGLExtensions(GLExtensions::getInstance()),
         mNeedsBlending(true),
-        mNeedsDithering(false)
+        mNeedsDithering(false),
+        mSecure(false),
+        mTextureManager(),
+        mBufferManager(mTextureManager),
+        mWidth(0), mHeight(0), mFixedSize(false)
 {
-    // no OpenGL operation is possible here, since we might not be
-    // in the OpenGL thread.
-    mFrontBufferIndex = lcblk->getFrontBuffer();
 }
 
 Layer::~Layer()
 {
-    destroy();
-    // the actual buffers will be destroyed here
+    // FIXME: must be called from the main UI thread
+    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+    mBufferManager.destroy(dpy);
+
+    // we can use getUserClientUnsafe here because we know we're
+    // single-threaded at that point.
+    sp<UserClient> ourClient(mUserClientRef.getUserClientUnsafe());
+    if (ourClient != 0) {
+        ourClient->detachLayer(this);
+    }
 }
 
-void Layer::destroy()
+status_t Layer::setToken(const sp<UserClient>& userClient,
+        SharedClient* sharedClient, int32_t token)
 {
-    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
-        if (mTextures[i].name != -1U) {
-            glDeleteTextures(1, &mTextures[i].name);
-            mTextures[i].name = -1U;
-        }
-        if (mTextures[i].image != EGL_NO_IMAGE_KHR) {
-            EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-            eglDestroyImageKHR(dpy, mTextures[i].image);
-            mTextures[i].image = EGL_NO_IMAGE_KHR;
-        }
-        Mutex::Autolock _l(mLock);
-        mBuffers[i].clear();
-        mWidth = mHeight = 0;
+    sp<SharedBufferServer> lcblk = new SharedBufferServer(
+            sharedClient, token, mBufferManager.getDefaultBufferCount(),
+            getIdentity());
+
+    status_t err = mUserClientRef.setToken(userClient, lcblk, token);
+
+    LOGE_IF(err != NO_ERROR,
+            "ClientRef::setToken(%p, %p, %u) failed",
+            userClient.get(), lcblk.get(), token);
+
+    if (err == NO_ERROR) {
+        // we need to free the buffers associated with this surface
     }
-    mSurface.clear();
+
+    return err;
+}
+
+int32_t Layer::getToken() const
+{
+    return mUserClientRef.getToken();
+}
+
+sp<UserClient> Layer::getClient() const
+{
+    return mUserClientRef.getClient();
+}
+
+// called with SurfaceFlinger::mStateLock as soon as the layer is entered
+// in the purgatory list
+void Layer::onRemoved()
+{
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    if (lcblk) {
+        // wake up the condition
+        lcblk->setStatus(NO_INIT);
+    }
 }
 
 sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -97,9 +124,17 @@
 
 status_t Layer::ditch()
 {
+    // NOTE: Called from the main UI thread
+
     // the layer is not on screen anymore. free as much resources as possible
     mFreezeLock.clear();
-    destroy();
+
+    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+    mBufferManager.destroy(dpy);
+    mSurface.clear();
+
+    Mutex::Autolock _l(mLock);
+    mWidth = mHeight = 0;
     return NO_ERROR;
 }
 
@@ -129,26 +164,26 @@
     mFormat = format;
     mWidth  = w;
     mHeight = h;
+
+    mReqFormat = format;
+    mReqWidth = w;
+    mReqHeight = h;
+
     mSecure = (flags & ISurfaceComposer::eSecure) ? true : false;
     mNeedsBlending = (info.h_alpha - info.l_alpha) > 0;
-    mNoEGLImageForSwBuffers = !(hwFlags & DisplayHardware::CACHED_BUFFERS);
 
     // we use the red index
     int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
     int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
     mNeedsDithering = layerRedsize > displayRedSize;
 
-    for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
-        mBuffers[i] = new GraphicBuffer();
-    }
-    mSurface = new SurfaceLayer(mFlinger, clientIndex(), this);
+    mSurface = new SurfaceLayer(mFlinger, this);
     return NO_ERROR;
 }
 
 void Layer::reloadTexture(const Region& dirty)
 {
-    Mutex::Autolock _l(mLock);
-    sp<GraphicBuffer> buffer(getFrontBufferLocked());
+    sp<GraphicBuffer> buffer(mBufferManager.getActiveBuffer());
     if (buffer == NULL) {
         // this situation can happen if we ran out of memory for instance.
         // not much we can do. continue to use whatever texture was bound
@@ -156,130 +191,33 @@
         return;
     }
 
-    const int index = mFrontBufferIndex;
-
-    // create the new texture name if needed
-    if (UNLIKELY(mTextures[index].name == -1U)) {
-        mTextures[index].name = createTexture();
-        mTextures[index].width = 0;
-        mTextures[index].height = 0;
-    }
-
-#ifdef EGL_ANDROID_image_native_buffer
-    if (mFlags & DisplayHardware::DIRECT_TEXTURE) {
-        if (buffer->usage & GraphicBuffer::USAGE_HW_TEXTURE) {
-            if (mTextures[index].dirty) {
-                if (initializeEglImage(buffer, &mTextures[index]) != NO_ERROR) {
-                    // not sure what we can do here...
-                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
-                    goto slowpath;
-                }
-            }
-        } else {
-            if (mHybridBuffer==0 || (mHybridBuffer->width != buffer->width ||
-                    mHybridBuffer->height != buffer->height)) {
-                mHybridBuffer.clear();
-                mHybridBuffer = new GraphicBuffer(
-                        buffer->width, buffer->height, buffer->format,
-                        GraphicBuffer::USAGE_SW_WRITE_OFTEN |
-                        GraphicBuffer::USAGE_HW_TEXTURE);
-                if (initializeEglImage(
-                        mHybridBuffer, &mTextures[0]) != NO_ERROR) {
-                    // not sure what we can do here...
-                    mFlags &= ~DisplayHardware::DIRECT_TEXTURE;
-                    mHybridBuffer.clear();
-                    goto slowpath;
-                }
-            }
-
-            GGLSurface t;
+    if (mGLExtensions.haveDirectTexture()) {
+        EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+        if (mBufferManager.initEglImage(dpy, buffer) != NO_ERROR) {
+            // not sure what we can do here...
+            goto slowpath;
+        }
+    } else {
+slowpath:
+        GGLSurface t;
+        if (buffer->usage & GRALLOC_USAGE_SW_READ_MASK) {
             status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
             LOGE_IF(res, "error %d (%s) locking buffer %p",
                     res, strerror(res), buffer.get());
             if (res == NO_ERROR) {
-                Texture* const texture(&mTextures[0]);
-
-                glBindTexture(GL_TEXTURE_2D, texture->name);
-
-                sp<GraphicBuffer> buf(mHybridBuffer);
-                void* vaddr;
-                res = buf->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN, &vaddr);
-                if (res == NO_ERROR) {
-                    int bpp = 0;
-                    switch (t.format) {
-                    case HAL_PIXEL_FORMAT_RGB_565:
-                    case HAL_PIXEL_FORMAT_RGBA_4444:
-                        bpp = 2;
-                        break;
-                    case HAL_PIXEL_FORMAT_RGBA_8888:
-                    case HAL_PIXEL_FORMAT_RGBX_8888:
-                        bpp = 4;
-                        break;
-                    default:
-                        if (isSupportedYuvFormat(t.format)) {
-                            // just show the Y plane of YUV buffers
-                            bpp = 1;
-                            break;
-                        }
-                        // oops, we don't handle this format!
-                        LOGE("layer %p, texture=%d, using format %d, which is not "
-                                "supported by the GL", this, texture->name, t.format);
-                    }
-                    if (bpp) {
-                        const Rect bounds(dirty.getBounds());
-                        size_t src_stride = t.stride;
-                        size_t dst_stride = buf->stride;
-                        if (src_stride == dst_stride &&
-                            bounds.width() == t.width &&
-                            bounds.height() == t.height)
-                        {
-                            memcpy(vaddr, t.data, t.height * t.stride * bpp);
-                        } else {
-                            GLubyte const * src = t.data +
-                                (bounds.left + bounds.top * src_stride) * bpp;
-                            GLubyte * dst = (GLubyte *)vaddr +
-                                (bounds.left + bounds.top * dst_stride) * bpp;
-                            const size_t length = bounds.width() * bpp;
-                            size_t h = bounds.height();
-                            src_stride *= bpp;
-                            dst_stride *= bpp;
-                            while (h--) {
-                                memcpy(dst, src, length);
-                                dst += dst_stride;
-                                src += src_stride;
-                            }
-                        }
-                    }
-                    buf->unlock();
-                }
+                mBufferManager.loadTexture(dirty, t);
                 buffer->unlock();
             }
-        }
-    } else
-#endif
-    {
-slowpath:
-        for (size_t i=0 ; i<NUM_BUFFERS ; i++) {
-            mTextures[i].image = EGL_NO_IMAGE_KHR;
-        }
-        GGLSurface t;
-        status_t res = buffer->lock(&t, GRALLOC_USAGE_SW_READ_OFTEN);
-        LOGE_IF(res, "error %d (%s) locking buffer %p",
-                res, strerror(res), buffer.get());
-        if (res == NO_ERROR) {
-            loadTexture(&mTextures[0], dirty, t);
-            buffer->unlock();
+        } else {
+            // we can't do anything
         }
     }
 }
 
 void Layer::onDraw(const Region& clip) const
 {
-    int index = mFrontBufferIndex;
-    if (mTextures[index].image == EGL_NO_IMAGE_KHR)
-        index = 0;
-    GLuint textureName = mTextures[index].name;
-    if (UNLIKELY(textureName == -1LU)) {
+    Texture tex(mBufferManager.getActiveTexture());
+    if (tex.name == -1LU) {
         // the texture has not been created yet, this Layer has
         // in fact never been drawn into. This happens frequently with
         // SurfaceView because the WindowManager can't know when the client
@@ -301,21 +239,61 @@
         // if not everything below us is covered, we plug the holes!
         Region holes(clip.subtract(under));
         if (!holes.isEmpty()) {
-            clearWithOpenGL(holes);
+            clearWithOpenGL(holes, 0, 0, 0, 1);
         }
         return;
     }
-    drawWithOpenGL(clip, mTextures[index]);
+    drawWithOpenGL(clip, tex);
 }
 
-sp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
+bool Layer::needsFiltering() const
+{
+    if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
+        // NOTE: there is a race here, because mFixedSize is updated in a
+        // binder transaction. however, it doesn't really matter since it is
+        // evaluated each time we draw. To be perfectly correct, this flag
+        // would have to be associated with a buffer.
+        if (mFixedSize)
+            return true;
+    }
+    return LayerBase::needsFiltering();
+}
+
+
+status_t Layer::setBufferCount(int bufferCount)
+{
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    if (!lcblk) {
+        // oops, the client is already gone
+        return DEAD_OBJECT;
+    }
+
+    // NOTE: lcblk->resize() is protected by an internal lock
+    status_t err = lcblk->resize(bufferCount);
+    if (err == NO_ERROR)
+        mBufferManager.resize(bufferCount);
+
+    return err;
+}
+
+sp<GraphicBuffer> Layer::requestBuffer(int index,
+        uint32_t reqWidth, uint32_t reqHeight, uint32_t reqFormat,
+        uint32_t usage)
 {
     sp<GraphicBuffer> buffer;
 
+    if (int32_t(reqWidth | reqHeight | reqFormat) < 0)
+        return buffer;
+
+    if ((!reqWidth && reqHeight) || (reqWidth && !reqHeight))
+        return buffer;
+
     // this ensures our client doesn't go away while we're accessing
     // the shared area.
-    sp<Client> ourClient(client.promote());
-    if (ourClient == 0) {
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    if (!lcblk) {
         // oops, the client is already gone
         return buffer;
     }
@@ -324,46 +302,38 @@
      * This is called from the client's Surface::dequeue(). This can happen
      * at any time, especially while we're in the middle of using the
      * buffer 'index' as our front buffer.
-     * 
-     * Make sure the buffer we're resizing is not the front buffer and has been
-     * dequeued. Once this condition is asserted, we are guaranteed that this
-     * buffer cannot become the front buffer under our feet, since we're called
-     * from Surface::dequeue()
      */
-    status_t err = lcblk->assertReallocate(index);
-    LOGE_IF(err, "assertReallocate(%d) failed (%s)", index, strerror(-err));
-    if (err != NO_ERROR) {
-        // the surface may have died
-        return buffer;
-    }
 
-    uint32_t w, h;
+    status_t err = NO_ERROR;
+    uint32_t w, h, f;
     { // scope for the lock
         Mutex::Autolock _l(mLock);
-        w = mWidth;
-        h = mHeight;
-        buffer = mBuffers[index];
-        
-        // destroy() could have been called before we get here, we log it
-        // because it's uncommon, and the code below should handle it
-        LOGW_IF(buffer==0, 
-                "mBuffers[%d] is null (mWidth=%d, mHeight=%d)",
-                index, w, h);
-        
-        mBuffers[index].clear();
+
+        // zero means default
+        if (!reqFormat) reqFormat = mFormat;
+        if (!reqWidth)  reqWidth = mWidth;
+        if (!reqHeight) reqHeight = mHeight;
+
+        w = reqWidth;
+        h = reqHeight;
+        f = reqFormat;
+
+        if ((reqWidth != mReqWidth) || (reqHeight != mReqHeight) ||
+                (reqFormat != mReqFormat)) {
+            mReqWidth  = reqWidth;
+            mReqHeight = reqHeight;
+            mReqFormat = reqFormat;
+
+            lcblk->reallocateAllExcept(index);
+        }
     }
 
+    // here we have to reallocate a new buffer because the buffer could be
+    // used as the front buffer, or by a client in our process
+    // (eg: status bar), and we can't release the handle under its feet.
     const uint32_t effectiveUsage = getEffectiveUsage(usage);
-    if (buffer!=0 && buffer->getStrongCount() == 1) {
-        err = buffer->reallocate(w, h, mFormat, effectiveUsage);
-    } else {
-        // here we have to reallocate a new buffer because we could have a
-        // client in our process with a reference to it (eg: status bar),
-        // and we can't release the handle under its feet.
-        buffer.clear();
-        buffer = new GraphicBuffer(w, h, mFormat, effectiveUsage);
-        err = buffer->initCheck();
-    }
+    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
+    err = buffer->initCheck();
 
     if (err || buffer->handle == 0) {
         LOGE_IF(err || buffer->handle == 0,
@@ -377,15 +347,7 @@
 
     if (err == NO_ERROR && buffer->handle != 0) {
         Mutex::Autolock _l(mLock);
-        if (mWidth && mHeight) {
-            // and we have new buffer
-            mBuffers[index] = buffer;
-            // texture is now dirty...
-            mTextures[index].dirty = true;
-        } else {
-            // oops we got killed while we were allocating the buffer
-            buffer.clear();
-        }
+        mBufferManager.attachBuffer(index, buffer);
     }
     return buffer;
 }
@@ -411,15 +373,8 @@
     } else {
         // it's allowed to modify the usage flags here, but generally
         // the requested flags should be honored.
-        if (mNoEGLImageForSwBuffers) {
-            if (usage & GraphicBuffer::USAGE_HW_MASK) {
-                // request EGLImage for h/w buffers only
-                usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-            }
-        } else {
-            // request EGLImage for all buffers
-            usage |= GraphicBuffer::USAGE_HW_TEXTURE;
-        }
+        // request EGLImage for all buffers
+        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
     }
     return usage;
 }
@@ -429,42 +384,50 @@
     const Layer::State& front(drawingState());
     const Layer::State& temp(currentState());
 
-    if ((front.requested_w != temp.requested_w) || 
-        (front.requested_h != temp.requested_h)) {
+    const bool sizeChanged = (front.requested_w != temp.requested_w) ||
+            (front.requested_h != temp.requested_h);
+
+    if (sizeChanged) {
         // the size changed, we need to ask our client to request a new buffer
         LOGD_IF(DEBUG_RESIZE,
-                    "resize (layer=%p), requested (%dx%d), "
-                    "drawing (%d,%d), (%dx%d), (%dx%d)",
-                    this, 
-                    int(temp.requested_w), int(temp.requested_h),
-                    int(front.requested_w), int(front.requested_h),
-                    int(mBuffers[0]->getWidth()), int(mBuffers[0]->getHeight()),
-                    int(mBuffers[1]->getWidth()), int(mBuffers[1]->getHeight()));
+                "resize (layer=%p), requested (%dx%d), drawing (%d,%d)",
+                this,
+                int(temp.requested_w), int(temp.requested_h),
+                int(front.requested_w), int(front.requested_h));
 
-        // we're being resized and there is a freeze display request,
-        // acquire a freeze lock, so that the screen stays put
-        // until we've redrawn at the new size; this is to avoid
-        // glitches upon orientation changes.
-        if (mFlinger->hasFreezeRequest()) {
-            // if the surface is hidden, don't try to acquire the
-            // freeze lock, since hidden surfaces may never redraw
-            if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
-                mFreezeLock = mFlinger->getFreezeLock();
+        if (!isFixedSize()) {
+            // we're being resized and there is a freeze display request,
+            // acquire a freeze lock, so that the screen stays put
+            // until we've redrawn at the new size; this is to avoid
+            // glitches upon orientation changes.
+            if (mFlinger->hasFreezeRequest()) {
+                // if the surface is hidden, don't try to acquire the
+                // freeze lock, since hidden surfaces may never redraw
+                if (!(front.flags & ISurfaceComposer::eLayerHidden)) {
+                    mFreezeLock = mFlinger->getFreezeLock();
+                }
             }
+
+            // this will make sure LayerBase::doTransaction doesn't update
+            // the drawing state's size
+            Layer::State& editDraw(mDrawingState);
+            editDraw.requested_w = temp.requested_w;
+            editDraw.requested_h = temp.requested_h;
+
+            // record the new size, form this point on, when the client request
+            // a buffer, it'll get the new size.
+            setBufferSize(temp.requested_w, temp.requested_h);
+
+            ClientRef::Access sharedClient(mUserClientRef);
+            SharedBufferServer* lcblk(sharedClient.get());
+            if (lcblk) {
+                // all buffers need reallocation
+                lcblk->reallocateAll();
+            }
+        } else {
+            // record the new size
+            setBufferSize(temp.requested_w, temp.requested_h);
         }
-
-        // this will make sure LayerBase::doTransaction doesn't update
-        // the drawing state's size
-        Layer::State& editDraw(mDrawingState);
-        editDraw.requested_w = temp.requested_w;
-        editDraw.requested_h = temp.requested_h;
-
-        // record the new size, form this point on, when the client request a
-        // buffer, it'll get the new size.
-        setDrawingSize(temp.requested_w, temp.requested_h);
-
-        // all buffers need reallocation
-        lcblk->reallocate();
     }
 
     if (temp.sequence != front.sequence) {
@@ -478,39 +441,55 @@
     return LayerBase::doTransaction(flags);
 }
 
-void Layer::setDrawingSize(uint32_t w, uint32_t h) {
+void Layer::setBufferSize(uint32_t w, uint32_t h) {
     Mutex::Autolock _l(mLock);
     mWidth = w;
     mHeight = h;
 }
 
+bool Layer::isFixedSize() const {
+    Mutex::Autolock _l(mLock);
+    return mFixedSize;
+}
+
 // ----------------------------------------------------------------------------
 // pageflip handling...
 // ----------------------------------------------------------------------------
 
 void Layer::lockPageFlip(bool& recomputeVisibleRegions)
 {
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    if (!lcblk) {
+        // client died
+        recomputeVisibleRegions = true;
+        return;
+    }
+
     ssize_t buf = lcblk->retireAndLock();
-    if (buf < NO_ERROR) {
-        //LOGW("nothing to retire (%s)", strerror(-buf));
-        // NOTE: here the buffer is locked because we will used 
+    if (buf == NOT_ENOUGH_DATA) {
+        // NOTE: This is not an error, it simply means there is nothing to
+        // retire. The buffer is locked because we will use it
         // for composition later in the loop
         return;
     }
 
-    // ouch, this really should never happen
-    if (uint32_t(buf)>=NUM_BUFFERS) {
-        LOGE("retireAndLock() buffer index (%d) out of range", buf);
+    if (buf < NO_ERROR) {
+        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
         mPostedDirtyRegion.clear();
         return;
     }
 
     // we retired a buffer, which becomes the new front buffer
-    mFrontBufferIndex = buf;
+    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
+        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
+        mPostedDirtyRegion.clear();
+        return;
+    }
 
-    // get the dirty region
     sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
     if (newFrontBuffer != NULL) {
+        // get the dirty region
         // compute the posted region
         const Region dirty(lcblk->getDirtyRegion(buf));
         mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
@@ -546,6 +525,13 @@
             // we now have the correct size, unfreeze the screen
             mFreezeLock.clear();
         }
+
+        // get the crop region
+        setBufferCrop( lcblk->getCrop(buf) );
+
+        // get the transformation
+        setBufferTransform( lcblk->getTransform(buf) );
+
     } else {
         // this should not happen unless we ran out of memory while
         // allocating the buffer. we're hoping that things will get back
@@ -559,9 +545,15 @@
         mFlinger->signalEvent();
     }
 
-    if (!mPostedDirtyRegion.isEmpty()) {
-        reloadTexture( mPostedDirtyRegion );
-    }
+    /* a buffer was posted, so we need to call reloadTexture(), which
+     * will update our internal data structures (eg: EGLImageKHR or
+     * texture names). we need to do this even if mPostedDirtyRegion is
+     * empty -- it's orthogonal to the fact that a new buffer was posted,
+     * for instance, a degenerate case could be that the user did an empty
+     * update but repainted the buffer with appropriate content (after a
+     * resize for instance).
+     */
+    reloadTexture( mPostedDirtyRegion );
 }
 
 void Layer::unlockPageFlip(
@@ -585,24 +577,265 @@
     }
     if (visibleRegionScreen.isEmpty()) {
         // an invisible layer should not hold a freeze-lock
-        // (because it may never be updated and thereore never release it)
+        // (because it may never be updated and therefore never release it)
         mFreezeLock.clear();
     }
 }
 
 void Layer::finishPageFlip()
 {
-    status_t err = lcblk->unlock( mFrontBufferIndex );
-    LOGE_IF(err!=NO_ERROR, 
-            "layer %p, buffer=%d wasn't locked!",
-            this, mFrontBufferIndex);
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    if (lcblk) {
+        int buf = mBufferManager.getActiveBufferIndex();
+        if (buf >= 0) {
+            status_t err = lcblk->unlock( buf );
+            LOGE_IF(err!=NO_ERROR,
+                    "layer %p, buffer=%d wasn't locked!",
+                    this, buf);
+        }
+    }
+}
+
+
+void Layer::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    LayerBaseClient::dump(result, buffer, SIZE);
+
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    uint32_t totalTime = 0;
+    if (lcblk) {
+        SharedBufferStack::Statistics stats = lcblk->getStats();
+        totalTime= stats.totalTime;
+        result.append( lcblk->dump("      ") );
+    }
+
+    sp<const GraphicBuffer> buf0(getBuffer(0));
+    sp<const GraphicBuffer> buf1(getBuffer(1));
+    uint32_t w0=0, h0=0, s0=0;
+    uint32_t w1=0, h1=0, s1=0;
+    if (buf0 != 0) {
+        w0 = buf0->getWidth();
+        h0 = buf0->getHeight();
+        s0 = buf0->getStride();
+    }
+    if (buf1 != 0) {
+        w1 = buf1->getWidth();
+        h1 = buf1->getHeight();
+        s1 = buf1->getStride();
+    }
+    snprintf(buffer, SIZE,
+            "      "
+            "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
+            " freezeLock=%p, dq-q-time=%u us\n",
+            mFormat, w0, h0, s0, w1, h1, s1,
+            getFreezeLock().get(), totalTime);
+
+    result.append(buffer);
+}
+
+// ---------------------------------------------------------------------------
+
+Layer::ClientRef::ClientRef()
+    : mControlBlock(0), mToken(-1) {
+}
+
+Layer::ClientRef::~ClientRef() {
+}
+
+int32_t Layer::ClientRef::getToken() const {
+    Mutex::Autolock _l(mLock);
+    return mToken;
+}
+
+sp<UserClient> Layer::ClientRef::getClient() const {
+    Mutex::Autolock _l(mLock);
+    return mUserClient.promote();
+}
+
+status_t Layer::ClientRef::setToken(const sp<UserClient>& uc,
+        const sp<SharedBufferServer>& sharedClient, int32_t token) {
+    Mutex::Autolock _l(mLock);
+
+    { // scope for strong mUserClient reference
+        sp<UserClient> userClient(mUserClient.promote());
+        if (mUserClient != 0 && mControlBlock != 0) {
+            mControlBlock->setStatus(NO_INIT);
+        }
+    }
+
+    mUserClient = uc;
+    mToken = token;
+    mControlBlock = sharedClient;
+    return NO_ERROR;
+}
+
+sp<UserClient> Layer::ClientRef::getUserClientUnsafe() const {
+    return mUserClient.promote();
+}
+
+// this class gives us access to SharedBufferServer safely
+// it makes sure the UserClient (and its associated shared memory)
+// won't go away while we're accessing it.
+Layer::ClientRef::Access::Access(const ClientRef& ref)
+    : mControlBlock(0)
+{
+    Mutex::Autolock _l(ref.mLock);
+    mUserClientStrongRef = ref.mUserClient.promote();
+    if (mUserClientStrongRef != 0)
+        mControlBlock = ref.mControlBlock;
+}
+
+Layer::ClientRef::Access::~Access()
+{
+}
+
+// ---------------------------------------------------------------------------
+
+Layer::BufferManager::BufferManager(TextureManager& tm)
+    : mNumBuffers(NUM_BUFFERS), mTextureManager(tm),
+      mActiveBuffer(-1), mFailover(false)
+{
+}
+
+Layer::BufferManager::~BufferManager()
+{
+}
+
+status_t Layer::BufferManager::resize(size_t size)
+{
+    Mutex::Autolock _l(mLock);
+    mNumBuffers = size;
+    return NO_ERROR;
+}
+
+// only for debugging
+sp<GraphicBuffer> Layer::BufferManager::getBuffer(size_t index) const {
+    return mBufferData[index].buffer;
+}
+
+status_t Layer::BufferManager::setActiveBufferIndex(size_t index) {
+    mActiveBuffer = index;
+    return NO_ERROR;
+}
+
+size_t Layer::BufferManager::getActiveBufferIndex() const {
+    return mActiveBuffer;
+}
+
+Texture Layer::BufferManager::getActiveTexture() const {
+    Texture res;
+    if (mFailover || mActiveBuffer<0) {
+        res = mFailoverTexture;
+    } else {
+        static_cast<Image&>(res) = mBufferData[mActiveBuffer].texture;
+    }
+    return res;
+}
+
+sp<GraphicBuffer> Layer::BufferManager::getActiveBuffer() const {
+    sp<GraphicBuffer> result;
+    const ssize_t activeBuffer = mActiveBuffer;
+    if (activeBuffer >= 0) {
+        BufferData const * const buffers = mBufferData;
+        Mutex::Autolock _l(mLock);
+        result = buffers[activeBuffer].buffer;
+    }
+    return result;
+}
+
+sp<GraphicBuffer> Layer::BufferManager::detachBuffer(size_t index)
+{
+    BufferData* const buffers = mBufferData;
+    sp<GraphicBuffer> buffer;
+    Mutex::Autolock _l(mLock);
+    buffer = buffers[index].buffer;
+    buffers[index].buffer = 0;
+    return buffer;
+}
+
+status_t Layer::BufferManager::attachBuffer(size_t index,
+        const sp<GraphicBuffer>& buffer)
+{
+    BufferData* const buffers = mBufferData;
+    Mutex::Autolock _l(mLock);
+    buffers[index].buffer = buffer;
+    buffers[index].texture.dirty = true;
+    return NO_ERROR;
+}
+
+status_t Layer::BufferManager::destroy(EGLDisplay dpy)
+{
+    BufferData* const buffers = mBufferData;
+    size_t num;
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+        num = mNumBuffers;
+        for (size_t i=0 ; i<num ; i++) {
+            buffers[i].buffer = 0;
+        }
+    }
+    for (size_t i=0 ; i<num ; i++) {
+        destroyTexture(&buffers[i].texture, dpy);
+    }
+    destroyTexture(&mFailoverTexture, dpy);
+    return NO_ERROR;
+}
+
+status_t Layer::BufferManager::initEglImage(EGLDisplay dpy,
+        const sp<GraphicBuffer>& buffer)
+{
+    status_t err = NO_INIT;
+    ssize_t index = mActiveBuffer;
+    if (index >= 0) {
+        if (!mFailover) {
+            Image& texture(mBufferData[index].texture);
+            err = mTextureManager.initEglImage(&texture, dpy, buffer);
+            // if EGLImage fails, we switch to regular texture mode, and we
+            // free all resources associated with using EGLImages.
+            if (err == NO_ERROR) {
+                mFailover = false;
+                destroyTexture(&mFailoverTexture, dpy);
+            } else {
+                mFailover = true;
+                const size_t num = mNumBuffers;
+                for (size_t i=0 ; i<num ; i++) {
+                    destroyTexture(&mBufferData[i].texture, dpy);
+                }
+            }
+        } else {
+            // we failed once, don't try again
+            err = BAD_VALUE;
+        }
+    }
+    return err;
+}
+
+status_t Layer::BufferManager::loadTexture(
+        const Region& dirty, const GGLSurface& t)
+{
+    return mTextureManager.loadTexture(&mFailoverTexture, dirty, t);
+}
+
+status_t Layer::BufferManager::destroyTexture(Image* tex, EGLDisplay dpy)
+{
+    if (tex->name != -1U) {
+        glDeleteTextures(1, &tex->name);
+        tex->name = -1U;
+    }
+    if (tex->image != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(dpy, tex->image);
+        tex->image = EGL_NO_IMAGE_KHR;
+    }
+    return NO_ERROR;
 }
 
 // ---------------------------------------------------------------------------
 
 Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
-        SurfaceID id, const sp<Layer>& owner)
-    : Surface(flinger, id, owner->getIdentity(), owner)
+        const sp<Layer>& owner)
+    : Surface(flinger, owner->getIdentity(), owner)
 {
 }
 
@@ -610,20 +843,37 @@
 {
 }
 
-sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int usage)
+sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index,
+        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
 {
     sp<GraphicBuffer> buffer;
     sp<Layer> owner(getOwner());
     if (owner != 0) {
-        LOGE_IF(uint32_t(index)>=NUM_BUFFERS,
-                "getBuffer() index (%d) out of range", index);
-        if (uint32_t(index) < NUM_BUFFERS) {
-            buffer = owner->requestBuffer(index, usage);
-        }
+        /*
+         * requestBuffer() cannot be called from the main thread
+         * as it could cause a dead-lock, since it may have to wait
+         * on conditions updated my the main thread.
+         */
+        buffer = owner->requestBuffer(index, w, h, format, usage);
     }
     return buffer;
 }
 
+status_t Layer::SurfaceLayer::setBufferCount(int bufferCount)
+{
+    status_t err = DEAD_OBJECT;
+    sp<Layer> owner(getOwner());
+    if (owner != 0) {
+        /*
+         * setBufferCount() cannot be called from the main thread
+         * as it could cause a dead-lock, since it may have to wait
+         * on conditions updated my the main thread.
+         */
+        err = owner->setBufferCount(bufferCount);
+    }
+    return err;
+}
+
 // ---------------------------------------------------------------------------
 
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 743afb4..e1d283b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -31,36 +31,43 @@
 
 #include "LayerBase.h"
 #include "Transform.h"
+#include "TextureManager.h"
 
 namespace android {
 
 // ---------------------------------------------------------------------------
 
-class Client;
 class FreezeLock;
+class Client;
+class GLExtensions;
+class UserClient;
 
 // ---------------------------------------------------------------------------
 
-const size_t NUM_BUFFERS = 2;
-
 class Layer : public LayerBaseClient
 {
-public:    
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
-                 Layer(SurfaceFlinger* flinger, DisplayID display,
-                         const sp<Client>& client, int32_t i);
+public:
+            Layer(SurfaceFlinger* flinger, DisplayID display,
+                    const sp<Client>& client);
 
-        virtual ~Layer();
+    virtual ~Layer();
 
+    virtual const char* getTypeId() const { return "Layer"; }
+
+    // the this layer's size and format
     status_t setBuffers(uint32_t w, uint32_t h, 
             PixelFormat format, uint32_t flags=0);
 
-    void setDrawingSize(uint32_t w, uint32_t h);
+    // associate a UserClient to this Layer
+    status_t setToken(const sp<UserClient>& uc, SharedClient* sc, int32_t idx);
+    int32_t getToken() const;
+    sp<UserClient> getClient() const;
 
+    // Set this Layer's buffers size
+    void setBufferSize(uint32_t w, uint32_t h);
+    bool isFixedSize() const;
+
+    // LayerBase interface
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t transactionFlags);
     virtual void lockPageFlip(bool& recomputeVisibleRegions);
@@ -68,63 +75,161 @@
     virtual void finishPageFlip();
     virtual bool needsBlending() const      { return mNeedsBlending; }
     virtual bool needsDithering() const     { return mNeedsDithering; }
+    virtual bool needsFiltering() const;
     virtual bool isSecure() const           { return mSecure; }
     virtual sp<Surface> createSurface() const;
     virtual status_t ditch();
-    
+    virtual void onRemoved();
+
     // only for debugging
-    inline sp<GraphicBuffer> getBuffer(int i) { return mBuffers[i]; }
+    inline sp<GraphicBuffer> getBuffer(int i) const {
+        return mBufferManager.getBuffer(i); }
     // only for debugging
-    inline const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
-    // only for debugging
-    inline PixelFormat pixelFormat() const { return mFormat; }
-    // only for debugging
-    inline int getFrontBufferIndex() const { return mFrontBufferIndex; }
+    inline const sp<FreezeLock>&  getFreezeLock() const {
+        return mFreezeLock; }
+
+protected:
+    virtual void dump(String8& result, char* scratch, size_t size) const;
 
 private:
-    inline sp<GraphicBuffer> getFrontBufferLocked() {
-        return mBuffers[mFrontBufferIndex];
-    }
- 
     void reloadTexture(const Region& dirty);
-
     uint32_t getEffectiveUsage(uint32_t usage) const;
+    sp<GraphicBuffer> requestBuffer(int bufferIdx,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+    status_t setBufferCount(int bufferCount);
 
-    sp<GraphicBuffer> requestBuffer(int index, int usage);
-    void destroy();
+    // -----------------------------------------------------------------------
 
     class SurfaceLayer : public LayerBaseClient::Surface {
     public:
-        SurfaceLayer(const sp<SurfaceFlinger>& flinger,
-                SurfaceID id, const sp<Layer>& owner);
+        SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner);
         ~SurfaceLayer();
     private:
-        virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
+        virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+                uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+        virtual status_t setBufferCount(int bufferCount);
         sp<Layer> getOwner() const {
             return static_cast<Layer*>(Surface::getOwner().get());
         }
     };
     friend class SurfaceLayer;
-    
-    sp<Surface>             mSurface;
 
-            bool            mSecure;
-            bool            mNoEGLImageForSwBuffers;
-            int32_t         mFrontBufferIndex;
-            bool            mNeedsBlending;
-            bool            mNeedsDithering;
-            Region          mPostedDirtyRegion;
-            sp<FreezeLock>  mFreezeLock;
-            PixelFormat     mFormat;
-            
-            // protected by mLock
-            sp<GraphicBuffer> mBuffers[NUM_BUFFERS];
-            Texture         mTextures[NUM_BUFFERS];
-            sp<GraphicBuffer> mHybridBuffer;
-            uint32_t        mWidth;
-            uint32_t        mHeight;
-            
-   mutable Mutex mLock;
+    // -----------------------------------------------------------------------
+
+    class ClientRef {
+        ClientRef(const ClientRef& rhs);
+        ClientRef& operator = (const ClientRef& rhs);
+        mutable Mutex mLock;
+        // binder thread, page-flip thread
+        sp<SharedBufferServer> mControlBlock;
+        wp<UserClient> mUserClient;
+        int32_t mToken;
+    public:
+        ClientRef();
+        ~ClientRef();
+        int32_t getToken() const;
+        sp<UserClient> getClient() const;
+        status_t setToken(const sp<UserClient>& uc,
+                const sp<SharedBufferServer>& sharedClient, int32_t token);
+        sp<UserClient> getUserClientUnsafe() const;
+        class Access {
+            Access(const Access& rhs);
+            Access& operator = (const Access& rhs);
+            sp<UserClient> mUserClientStrongRef;
+            sp<SharedBufferServer> mControlBlock;
+        public:
+            Access(const ClientRef& ref);
+            ~Access();
+            inline SharedBufferServer* get() const { return mControlBlock.get(); }
+        };
+        friend class Access;
+    };
+
+    // -----------------------------------------------------------------------
+
+    class BufferManager {
+        static const size_t NUM_BUFFERS = 2;
+        struct BufferData {
+            sp<GraphicBuffer>   buffer;
+            Image               texture;
+        };
+        // this lock protect mBufferData[].buffer but since there
+        // is very little contention, we have only one like for
+        // the whole array, we also use it to protect mNumBuffers.
+        mutable Mutex mLock;
+        BufferData          mBufferData[SharedBufferStack::NUM_BUFFER_MAX];
+        size_t              mNumBuffers;
+        Texture             mFailoverTexture;
+        TextureManager&     mTextureManager;
+        ssize_t             mActiveBuffer;
+        bool                mFailover;
+        static status_t destroyTexture(Image* tex, EGLDisplay dpy);
+
+    public:
+        static size_t getDefaultBufferCount() { return NUM_BUFFERS; }
+        BufferManager(TextureManager& tm);
+        ~BufferManager();
+
+        // detach/attach buffer from/to given index
+        sp<GraphicBuffer> detachBuffer(size_t index);
+        status_t attachBuffer(size_t index, const sp<GraphicBuffer>& buffer);
+        // resize the number of active buffers
+        status_t resize(size_t size);
+
+        // ----------------------------------------------
+        // must be called from GL thread
+
+        // set/get active buffer index
+        status_t setActiveBufferIndex(size_t index);
+        size_t getActiveBufferIndex() const;
+        // return the active buffer
+        sp<GraphicBuffer> getActiveBuffer() const;
+        // return the active texture (or fail-over)
+        Texture getActiveTexture() const;
+        // frees resources associated with all buffers
+        status_t destroy(EGLDisplay dpy);
+        // load bitmap data into the active buffer
+        status_t loadTexture(const Region& dirty, const GGLSurface& t);
+        // make active buffer an EGLImage if needed
+        status_t initEglImage(EGLDisplay dpy,
+                const sp<GraphicBuffer>& buffer);
+
+        // ----------------------------------------------
+        // only for debugging
+        sp<GraphicBuffer> getBuffer(size_t index) const;
+    };
+
+    // -----------------------------------------------------------------------
+
+    // thread-safe
+    ClientRef mUserClientRef;
+
+    // constants
+    sp<Surface> mSurface;
+    PixelFormat mFormat;
+    const GLExtensions& mGLExtensions;
+    bool mNeedsBlending;
+    bool mNeedsDithering;
+
+    // page-flip thread (currently main thread)
+    bool mSecure;
+    Region mPostedDirtyRegion;
+
+    // page-flip thread and transaction thread (currently main thread)
+    sp<FreezeLock>  mFreezeLock;
+
+    // see threading usage in declaration
+    TextureManager mTextureManager;
+    BufferManager mBufferManager;
+
+    // binder thread, transaction thread
+    mutable Mutex mLock;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mReqWidth;
+    uint32_t mReqHeight;
+    uint32_t mReqFormat;
+    bool mFixedSize;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index a8b735e..6fc5010 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -32,33 +32,30 @@
 #include "LayerBase.h"
 #include "SurfaceFlinger.h"
 #include "DisplayHardware/DisplayHardware.h"
+#include "TextureManager.h"
 
 
 namespace android {
 
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerBase::typeInfo = 1;
-const char* const LayerBase::typeID = "LayerBase";
-
-const uint32_t LayerBaseClient::typeInfo = LayerBase::typeInfo | 2;
-const char* const LayerBaseClient::typeID = "LayerBaseClient";
-
-// ---------------------------------------------------------------------------
+int32_t LayerBase::sSequence = 1;
 
 LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
     : dpy(display), contentDirty(false),
+      sequence(uint32_t(android_atomic_inc(&sSequence))),
       mFlinger(flinger),
-      mTransformed(false),
-      mUseLinearFiltering(false),
+      mNeedsFiltering(false),
       mOrientation(0),
       mLeft(0), mTop(0),
       mTransactionFlags(0),
-      mPremultipliedAlpha(true), mDebug(false),
+      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
       mInvalidate(0)
 {
     const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
     mFlags = hw.getFlags();
+    mBufferCrop.makeInvalid();
+    mBufferTransform = 0;
 }
 
 LayerBase::~LayerBase()
@@ -159,7 +156,6 @@
     return true;
 }
 bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
-    // TODO: check the matrix has changed
     mCurrentState.sequence++;
     mCurrentState.transform.set(
             matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
@@ -167,7 +163,6 @@
     return true;
 }
 bool LayerBase::setTransparentRegionHint(const Region& transparent) {
-    // TODO: check the region has changed
     mCurrentState.sequence++;
     mCurrentState.transparentRegion = transparent;
     requestTransaction();
@@ -221,13 +216,12 @@
         flags |= eVisibleRegion;
         this->contentDirty = true;
 
-        const bool linearFiltering = mUseLinearFiltering;
-        mUseLinearFiltering = false;
+        mNeedsFiltering = false;
         if (!(mFlags & DisplayHardware::SLOW_CONFIG)) {
             // we may use linear filtering, if the matrix scales us
             const uint8_t type = temp.transform.getType();
             if (!temp.transform.preserveRects() || (type >= Transform::SCALE)) {
-                mUseLinearFiltering = true;
+                mNeedsFiltering = true;
             }
         }
     }
@@ -267,7 +261,6 @@
     // cache a few things...
     mOrientation = tr.getOrientation();
     mTransformedBounds = tr.makeBounds(w, h);
-    mTransformed = transformed;
     mLeft = tr.tx();
     mTop  = tr.ty();
 }
@@ -316,65 +309,31 @@
     }
 }
 
-void LayerBase::draw(const Region& inClip) const
+void LayerBase::draw(const Region& clip) const
 {
-    // invalidate the region we'll update
-    Region clip(inClip);  // copy-on-write, so no-op most of the time
-
-    // Remove the transparent area from the clipping region
-    const State& s = drawingState();
-    if (LIKELY(!s.transparentRegion.isEmpty())) {
-        clip.subtract(transparentRegionScreen);
-        if (clip.isEmpty()) {
-            // usually this won't happen because this should be taken care of
-            // by SurfaceFlinger::computeVisibleRegions()
-            return;
-        }        
-    }
-
     // reset GL state
     glEnable(GL_SCISSOR_TEST);
 
     onDraw(clip);
-
-    /*
-    glDisable(GL_TEXTURE_2D);
-    glDisable(GL_DITHER);
-    glEnable(GL_BLEND);
-    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-    glColor4x(0, 0x8000, 0, 0x10000);
-    drawRegion(transparentRegionScreen);
-    glDisable(GL_BLEND);
-    */
 }
 
-GLuint LayerBase::createTexture() const
-{
-    GLuint textureName = -1;
-    glGenTextures(1, &textureName);
-    glBindTexture(GL_TEXTURE_2D, textureName);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    return textureName;
-}
-
-void LayerBase::clearWithOpenGL(const Region& clip, GLclampx red,
-                                GLclampx green, GLclampx blue,
-                                GLclampx alpha) const
+void LayerBase::clearWithOpenGL(const Region& clip, GLclampf red,
+                                GLclampf green, GLclampf blue,
+                                GLclampf alpha) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
     const uint32_t fbHeight = hw.getHeight();
-    glColor4x(red,green,blue,alpha);
-    glDisable(GL_TEXTURE_2D);
+    glColor4f(red,green,blue,alpha);
+
+    TextureManager::deactivateTextures();
+
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
 
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
     glEnable(GL_SCISSOR_TEST);
-    glVertexPointer(2, GL_FIXED, 0, mVertices);
+    glVertexPointer(2, GL_FLOAT, 0, mVertices);
     while (it != end) {
         const Rect& r = *it++;
         const GLint sy = fbHeight - (r.top + r.height());
@@ -388,6 +347,14 @@
     clearWithOpenGL(clip,0,0,0,0);
 }
 
+template <typename T>
+static inline
+void swap(T& a, T& b) {
+    T t(a);
+    a = b;
+    b = t;
+}
+
 void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
 {
     const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -395,39 +362,25 @@
     const State& s(drawingState());
     
     // bind our texture
-    validateTexture(texture.name);
+    TextureManager::activateTexture(texture, needsFiltering());
     uint32_t width  = texture.width; 
     uint32_t height = texture.height;
-    
-    glEnable(GL_TEXTURE_2D);
 
+    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
     if (UNLIKELY(s.alpha < 0xFF)) {
-        // We have an alpha-modulation. We need to modulate all
-        // texture components by alpha because we're always using 
-        // premultiplied alpha.
-        
-        // If the texture doesn't have an alpha channel we can
-        // use REPLACE and switch to non premultiplied alpha
-        // blending (SRCA/ONE_MINUS_SRCA).
-        
-        GLenum env, src;
-        if (needsBlending()) {
-            env = GL_MODULATE;
-            src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+        const GLfloat alpha = s.alpha * (1.0f/255.0f);
+        if (mPremultipliedAlpha) {
+            glColor4f(alpha, alpha, alpha, alpha);
         } else {
-            env = GL_REPLACE;
-            src = GL_SRC_ALPHA;
+            glColor4f(1, 1, 1, alpha);
         }
-        const GGLfixed alpha = (s.alpha << 16)/255;
-        glColor4x(alpha, alpha, alpha, alpha);
         glEnable(GL_BLEND);
         glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, env);
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
     } else {
+        glColor4f(1, 1, 1, 1);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
         if (needsBlending()) {
-            GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
             glEnable(GL_BLEND);
             glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
         } else {
@@ -435,44 +388,85 @@
         }
     }
 
-    Region::const_iterator it = clip.begin();
-    Region::const_iterator const end = clip.end();
+    /*
+     *  compute texture coordinates
+     *  here, we handle NPOT, cropping and buffer transformations
+     */
 
-    //StopWatch watch("GL transformed");
-    const GLfixed texCoords[4][2] = {
-            { 0,        0 },
-            { 0,        0x10000 },
-            { 0x10000,  0x10000 },
-            { 0x10000,  0 }
-    };
-
-    glMatrixMode(GL_TEXTURE);
-    glLoadIdentity();
-
-    // the texture's source is rotated
-    switch (texture.transform) {
-        case HAL_TRANSFORM_ROT_90:
-            glTranslatef(0, 1, 0);
-            glRotatef(-90, 0, 0, 1);
-            break;
-        case HAL_TRANSFORM_ROT_180:
-            glTranslatef(1, 1, 0);
-            glRotatef(-180, 0, 0, 1);
-            break;
-        case HAL_TRANSFORM_ROT_270:
-            glTranslatef(1, 0, 0);
-            glRotatef(-270, 0, 0, 1);
-            break;
+    GLfloat cl, ct, cr, cb;
+    if (!mBufferCrop.isEmpty()) {
+        // source is cropped
+        const GLfloat us = (texture.NPOTAdjust ? texture.wScale : 1.0f) / width;
+        const GLfloat vs = (texture.NPOTAdjust ? texture.hScale : 1.0f) / height;
+        cl = mBufferCrop.left   * us;
+        ct = mBufferCrop.top    * vs;
+        cr = mBufferCrop.right  * us;
+        cb = mBufferCrop.bottom * vs;
+    } else {
+        cl = 0;
+        ct = 0;
+        cr = (texture.NPOTAdjust ? texture.wScale : 1.0f);
+        cb = (texture.NPOTAdjust ? texture.hScale : 1.0f);
     }
 
-    if (texture.NPOTAdjust) {
-        glScalef(texture.wScale, texture.hScale, 1.0f);
+    struct TexCoords {
+        GLfloat u;
+        GLfloat v;
+    };
+
+    enum {
+        // name of the corners in the texture map
+        LB = 0, // left-bottom
+        LT = 1, // left-top
+        RT = 2, // right-top
+        RB = 3  // right-bottom
+    };
+
+    // vertices in screen space
+    int vLT = LB;
+    int vLB = LT;
+    int vRB = RT;
+    int vRT = RB;
+
+    // the texture's source is rotated
+    uint32_t transform = mBufferTransform;
+    if (transform & HAL_TRANSFORM_ROT_90) {
+        vLT = RB;
+        vLB = LB;
+        vRB = LT;
+        vRT = RT;
+    }
+    if (transform & HAL_TRANSFORM_FLIP_V) {
+        swap(vLT, vLB);
+        swap(vRB, vRT);
+    }
+    if (transform & HAL_TRANSFORM_FLIP_H) {
+        swap(vLT, vRB);
+        swap(vLB, vRT);
+    }
+
+    TexCoords texCoords[4];
+    texCoords[vLT].u = cl;
+    texCoords[vLT].v = ct;
+    texCoords[vLB].u = cl;
+    texCoords[vLB].v = cb;
+    texCoords[vRB].u = cr;
+    texCoords[vRB].v = cb;
+    texCoords[vRT].u = cr;
+    texCoords[vRT].v = ct;
+
+    if (needsDithering()) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
     }
 
     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    glVertexPointer(2, GL_FIXED, 0, mVertices);
-    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
+    glVertexPointer(2, GL_FLOAT, 0, mVertices);
+    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
 
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
     while (it != end) {
         const Rect& r = *it++;
         const GLint sy = fbHeight - (r.top + r.height());
@@ -482,246 +476,50 @@
     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 }
 
-void LayerBase::validateTexture(GLint textureName) const
-{
-    glBindTexture(GL_TEXTURE_2D, textureName);
-    // TODO: reload the texture if needed
-    // this is currently done in loadTexture() below
-    if (mUseLinearFiltering) {
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-    } else {
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    }
-
-    if (needsDithering()) {
-        glEnable(GL_DITHER);
-    } else {
-        glDisable(GL_DITHER);
+void LayerBase::setBufferCrop(const Rect& crop) {
+    if (!crop.isEmpty()) {
+        mBufferCrop = crop;
     }
 }
 
-bool LayerBase::isSupportedYuvFormat(int format) const
-{
-    switch (format) {
-        case HAL_PIXEL_FORMAT_YCbCr_422_SP:
-        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
-        case HAL_PIXEL_FORMAT_YCbCr_422_P:
-        case HAL_PIXEL_FORMAT_YCbCr_420_P:
-        case HAL_PIXEL_FORMAT_YCbCr_422_I:
-        case HAL_PIXEL_FORMAT_YCbCr_420_I:
-        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
-            return true;
-    }
-    return false;
+void LayerBase::setBufferTransform(uint32_t transform) {
+    mBufferTransform = transform;
 }
 
-void LayerBase::loadTexture(Texture* texture, 
-        const Region& dirty, const GGLSurface& t) const
+void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
 {
-    if (texture->name == -1U) {
-        // uh?
-        return;
-    }
-
-    glBindTexture(GL_TEXTURE_2D, texture->name);
-
-    /*
-     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
-     * GL_UNPACK_ALIGNMENT is a limited form of stride).
-     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
-     * need to do something reasonable (here creating a bigger texture).
-     * 
-     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
-     * 
-     * This situation doesn't happen often, but some h/w have a limitation
-     * for their framebuffer (eg: must be multiple of 8 pixels), and
-     * we need to take that into account when using these buffers as
-     * textures.
-     *
-     * This should never be a problem with POT textures
-     */
-    
-    int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
-    unpack = 1 << ((unpack > 3) ? 3 : unpack);
-    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
-    
-    /*
-     * round to POT if needed 
-     */
-    if (!(mFlags & DisplayHardware::NPOT_EXTENSION)) {
-        texture->NPOTAdjust = true;
-    }
-    
-    if (texture->NPOTAdjust) {
-        // find the smallest power-of-two that will accommodate our surface
-        texture->potWidth  = 1 << (31 - clz(t.width));
-        texture->potHeight = 1 << (31 - clz(t.height));
-        if (texture->potWidth  < t.width)  texture->potWidth  <<= 1;
-        if (texture->potHeight < t.height) texture->potHeight <<= 1;
-        texture->wScale = float(t.width)  / texture->potWidth;
-        texture->hScale = float(t.height) / texture->potHeight;
-    } else {
-        texture->potWidth  = t.width;
-        texture->potHeight = t.height;
-    }
-
-    Rect bounds(dirty.bounds());
-    GLvoid* data = 0;
-    if (texture->width != t.width || texture->height != t.height) {
-        texture->width  = t.width;
-        texture->height = t.height;
-
-        // texture size changed, we need to create a new one
-        bounds.set(Rect(t.width, t.height));
-        if (t.width  == texture->potWidth &&
-            t.height == texture->potHeight) {
-            // we can do it one pass
-            data = t.data;
-        }
-
-        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
-            glTexImage2D(GL_TEXTURE_2D, 0,
-                    GL_RGB, texture->potWidth, texture->potHeight, 0,
-                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
-        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
-            glTexImage2D(GL_TEXTURE_2D, 0,
-                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
-                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
-        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
-                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
-            glTexImage2D(GL_TEXTURE_2D, 0,
-                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
-                    GL_RGBA, GL_UNSIGNED_BYTE, data);
-        } else if (isSupportedYuvFormat(t.format)) {
-            // just show the Y plane of YUV buffers
-            glTexImage2D(GL_TEXTURE_2D, 0,
-                    GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
-                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
-        } else {
-            // oops, we don't handle this format!
-            LOGE("layer %p, texture=%d, using format %d, which is not "
-                 "supported by the GL", this, texture->name, t.format);
-        }
-    }
-    if (!data) {
-        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
-            glTexSubImage2D(GL_TEXTURE_2D, 0,
-                    0, bounds.top, t.width, bounds.height(),
-                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
-                    t.data + bounds.top*t.stride*2);
-        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
-            glTexSubImage2D(GL_TEXTURE_2D, 0,
-                    0, bounds.top, t.width, bounds.height(),
-                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
-                    t.data + bounds.top*t.stride*2);
-        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
-                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
-            glTexSubImage2D(GL_TEXTURE_2D, 0,
-                    0, bounds.top, t.width, bounds.height(),
-                    GL_RGBA, GL_UNSIGNED_BYTE,
-                    t.data + bounds.top*t.stride*4);
-        } else if (isSupportedYuvFormat(t.format)) {
-            // just show the Y plane of YUV buffers
-            glTexSubImage2D(GL_TEXTURE_2D, 0,
-                    0, bounds.top, t.width, bounds.height(),
-                    GL_LUMINANCE, GL_UNSIGNED_BYTE,
-                    t.data + bounds.top*t.stride);
-        }
-    }
+    const Layer::State& s(drawingState());
+    snprintf(buffer, SIZE,
+            "+ %s %p\n"
+            "      "
+            "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
+            "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
+            "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
+            getTypeId(), this, s.z, tx(), ty(), s.w, s.h,
+            needsBlending(), needsDithering(), contentDirty,
+            s.alpha, s.flags,
+            s.transform[0][0], s.transform[0][1],
+            s.transform[1][0], s.transform[1][1]);
+    result.append(buffer);
 }
 
-status_t LayerBase::initializeEglImage(
-        const sp<GraphicBuffer>& buffer, Texture* texture)
-{
-    status_t err = NO_ERROR;
-
-    // we need to recreate the texture
-    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
-
-    // free the previous image
-    if (texture->image != EGL_NO_IMAGE_KHR) {
-        eglDestroyImageKHR(dpy, texture->image);
-        texture->image = EGL_NO_IMAGE_KHR;
-    }
-
-    // construct an EGL_NATIVE_BUFFER_ANDROID
-    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
-
-    // create the new EGLImageKHR
-    const EGLint attrs[] = {
-            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
-            EGL_NONE,                   EGL_NONE
-    };
-    texture->image = eglCreateImageKHR(
-            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
-            (EGLClientBuffer)clientBuf, attrs);
-
-    if (texture->image != EGL_NO_IMAGE_KHR) {
-        glBindTexture(GL_TEXTURE_2D, texture->name);
-        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D,
-                (GLeglImageOES)texture->image);
-        GLint error = glGetError();
-        if (UNLIKELY(error != GL_NO_ERROR)) {
-            LOGE("layer=%p, glEGLImageTargetTexture2DOES(%p) "
-                 "failed err=0x%04x",
-                 this, texture->image, error);
-            err = INVALID_OPERATION;
-        } else {
-            // Everything went okay!
-            texture->NPOTAdjust = false;
-            texture->dirty  = false;
-            texture->width  = clientBuf->width;
-            texture->height = clientBuf->height;
-        }
-    } else {
-        LOGE("layer=%p, eglCreateImageKHR() failed. err=0x%4x",
-                this, eglGetError());
-        err = INVALID_OPERATION;
-    }
-    return err;
-}
-
-
 // ---------------------------------------------------------------------------
 
-int32_t LayerBaseClient::sIdentity = 0;
+int32_t LayerBaseClient::sIdentity = 1;
 
 LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client, int32_t i)
-    : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
+        const sp<Client>& client)
+    : LayerBase(flinger, display), mClientRef(client),
       mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
 {
-    lcblk = new SharedBufferServer(
-            client->ctrlblk, i, NUM_BUFFERS,
-            mIdentity);
-}
-
-void LayerBaseClient::onFirstRef()
-{    
-    sp<Client> client(this->client.promote());
-    if (client != 0) {
-        client->bindLayer(this, mIndex);
-    }
 }
 
 LayerBaseClient::~LayerBaseClient()
 {
-    sp<Client> client(this->client.promote());
-    if (client != 0) {
-        client->free(mIndex);
+    sp<Client> c(mClientRef.promote());
+    if (c != 0) {
+        c->detachLayer(this);
     }
-    delete lcblk;
-}
-
-int32_t LayerBaseClient::serverIndex() const 
-{
-    sp<Client> client(this->client.promote());
-    if (client != 0) {
-        return (client->cid<<16)|mIndex;
-    }
-    return 0xFFFF0000 | mIndex;
 }
 
 sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
@@ -738,25 +536,31 @@
 
 sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
 {
-    return new Surface(mFlinger, clientIndex(), mIdentity,
+    return new Surface(mFlinger, mIdentity,
             const_cast<LayerBaseClient *>(this));
 }
 
-// called with SurfaceFlinger::mStateLock as soon as the layer is entered
-// in the purgatory list
-void LayerBaseClient::onRemoved()
+void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
 {
-    // wake up the condition
-    lcblk->setStatus(NO_INIT);
+    LayerBase::dump(result, buffer, SIZE);
+
+    sp<Client> client(mClientRef.promote());
+    snprintf(buffer, SIZE,
+            "      name=%s\n"
+            "      client=%p, identity=%u\n",
+            getName().string(),
+            client.get(), getIdentity());
+
+    result.append(buffer);
 }
 
 // ---------------------------------------------------------------------------
 
 LayerBaseClient::Surface::Surface(
         const sp<SurfaceFlinger>& flinger,
-        SurfaceID id, int identity, 
+        int identity,
         const sp<LayerBaseClient>& owner) 
-    : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner)
+    : mFlinger(flinger), mIdentity(identity), mOwner(owner)
 {
 }
 
@@ -799,11 +603,17 @@
     return BnSurface::onTransact(code, data, reply, flags);
 }
 
-sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 
+sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int bufferIdx,
+        uint32_t w, uint32_t h, uint32_t format, uint32_t usage)
 {
     return NULL; 
 }
 
+status_t LayerBaseClient::Surface::setBufferCount(int bufferCount)
+{
+    return INVALID_OPERATION;
+}
+
 status_t LayerBaseClient::Surface::registerBuffers(
         const ISurface::BufferHeap& buffers) 
 { 
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 62ec839..8cba287 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -29,7 +29,7 @@
 #include <ui/Region.h>
 #include <ui/Overlay.h>
 
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 #include <private/surfaceflinger/SharedBufferStack.h>
 #include <private/surfaceflinger/LayerState.h>
 
@@ -45,46 +45,25 @@
 class Client;
 class GraphicBuffer;
 class GraphicPlane;
+class LayerBaseClient;
 class SurfaceFlinger;
+class Texture;
 
 // ---------------------------------------------------------------------------
 
 class LayerBase : public RefBase
 {
-    // poor man's dynamic_cast below
-    template<typename T>
-    struct getTypeInfoOfAnyType {
-        static uint32_t get() { return T::typeInfo; }
-    };
-
-    template<typename T>
-    struct getTypeInfoOfAnyType<T*> {
-        static uint32_t get() { return getTypeInfoOfAnyType<T>::get(); }
-    };
+    static int32_t sSequence;
 
 public:
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
-    template<typename T>
-    static T dynamicCast(LayerBase* base) {
-        uint32_t mostDerivedInfo = base->getTypeInfo();
-        uint32_t castToInfo = getTypeInfoOfAnyType<T>::get();
-        if ((mostDerivedInfo & castToInfo) == castToInfo)
-            return static_cast<T>(base);
-        return 0;
-    }
+            LayerBase(SurfaceFlinger* flinger, DisplayID display);
 
-    
-    LayerBase(SurfaceFlinger* flinger, DisplayID display);
-    
     DisplayID           dpy;
     mutable bool        contentDirty;
             Region      visibleRegionScreen;
             Region      transparentRegionScreen;
             Region      coveredRegionScreen;
+            int32_t     sequence;
             
             struct State {
                 uint32_t        w;
@@ -125,6 +104,10 @@
 
             void invalidate();
 
+    virtual sp<LayerBaseClient> getLayerBaseClient() const { return 0; }
+
+    virtual const char* getTypeId() const { return "LayerBase"; }
+
     /**
      * draw - performs some global clipping optimizations
      * and calls onDraw().
@@ -199,9 +182,9 @@
     virtual bool needsDithering() const { return false; }
 
     /**
-     * transformed -- true is this surface needs a to be transformed
+     * needsLinearFiltering - true if this surface needs filtering
      */
-    virtual bool transformed() const    { return mTransformed; }
+    virtual bool needsFiltering() const { return mNeedsFiltering; }
 
     /**
      * isSecure - true if this surface is secure, that is if it prevents
@@ -217,7 +200,10 @@
      *  current list */
     virtual void onRemoved() { };
     
-    
+    /** always call base class first */
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
+
     enum { // flags for doTransaction()
         eVisibleRegion      = 0x00000002,
     };
@@ -227,12 +213,6 @@
     inline  const State&    currentState() const    { return mCurrentState; }
     inline  State&          currentState()          { return mCurrentState; }
 
-    static int compareCurrentStateZ(
-            sp<LayerBase> const * layerA,
-            sp<LayerBase> const * layerB) {
-        return layerA[0]->currentState().z - layerB[0]->currentState().z;
-    }
-
     int32_t  getOrientation() const { return mOrientation; }
     int  tx() const             { return mLeft; }
     int  ty() const             { return mTop; }
@@ -241,44 +221,26 @@
     const GraphicPlane& graphicPlane(int dpy) const;
           GraphicPlane& graphicPlane(int dpy);
 
-          GLuint createTexture() const;
-    
-          struct Texture {
-              Texture() : name(-1U), width(0), height(0),
-                  image(EGL_NO_IMAGE_KHR), transform(0), 
-                  NPOTAdjust(false), dirty(true) { }
-              GLuint        name;
-              GLuint        width;
-              GLuint        height;
-              GLuint        potWidth;
-              GLuint        potHeight;
-              GLfloat       wScale;
-              GLfloat       hScale;
-              EGLImageKHR   image;
-              uint32_t      transform;
-              bool          NPOTAdjust;
-              bool          dirty;
-          };
-
-          void clearWithOpenGL(const Region& clip, GLclampx r, GLclampx g,
-                               GLclampx b, GLclampx alpha) const;
+          void clearWithOpenGL(const Region& clip, GLclampf r, GLclampf g,
+                               GLclampf b, GLclampf alpha) const;
           void clearWithOpenGL(const Region& clip) const;
           void drawWithOpenGL(const Region& clip, const Texture& texture) const;
-          void loadTexture(Texture* texture, 
-                  const Region& dirty, const GGLSurface& t) const;
-          status_t initializeEglImage(
-                  const sp<GraphicBuffer>& buffer, Texture* texture);
-
-          bool isSupportedYuvFormat(int format) const;
           
+          // these must be called from the post/drawing thread
+          void setBufferCrop(const Rect& crop);
+          void setBufferTransform(uint32_t transform);
+
                 sp<SurfaceFlinger> mFlinger;
                 uint32_t        mFlags;
 
+                // post/drawing thread
+                Rect mBufferCrop;
+                uint32_t mBufferTransform;
+
                 // cached during validateVisibility()
-                bool            mTransformed;
-                bool            mUseLinearFiltering;
+                bool            mNeedsFiltering;
                 int32_t         mOrientation;
-                GLfixed         mVertices[4][2];
+                GLfloat         mVertices[4][2];
                 Rect            mTransformedBounds;
                 int             mLeft;
                 int             mTop;
@@ -303,7 +265,6 @@
 
 private:
     LayerBase(const LayerBase& rhs);
-    void validateTexture(GLint textureName) const;
 };
 
 
@@ -313,42 +274,25 @@
 {
 public:
     class Surface;
-   static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
 
-    // lcblk is (almost) only accessed from the main SF thread, in the places
-    // where it's not, a reference to Client must be held
-    SharedBufferServer*     lcblk;
-
-    LayerBaseClient(SurfaceFlinger* flinger, DisplayID display, 
-            const sp<Client>& client, int32_t i);
+            LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+                        const sp<Client>& client);
     virtual ~LayerBaseClient();
-    virtual void onFirstRef();
 
-    const wp<Client>    client;
-
-    inline  uint32_t    getIdentity() const { return mIdentity; }
-    inline  int32_t     clientIndex() const { return mIndex; }
-            int32_t     serverIndex() const;
-
-   
             sp<Surface> getSurface();
     virtual sp<Surface> createSurface() const;
-    
-    virtual void onRemoved();
+    virtual sp<LayerBaseClient> getLayerBaseClient() const {
+        return const_cast<LayerBaseClient*>(this); }
+    virtual const char* getTypeId() const { return "LayerBaseClient"; }
 
+    uint32_t getIdentity() const { return mIdentity; }
 
-    class Surface : public BnSurface 
-    {
+    class Surface : public BnSurface  {
     public:
-        int32_t getToken() const { return mToken; }
         int32_t getIdentity() const { return mIdentity; }
         
     protected:
-        Surface(const sp<SurfaceFlinger>& flinger, 
-                SurfaceID id, int identity, 
+        Surface(const sp<SurfaceFlinger>& flinger, int identity,
                 const sp<LayerBaseClient>& owner);
         virtual ~Surface();
         virtual status_t onTransact(uint32_t code, const Parcel& data,
@@ -356,7 +300,10 @@
         sp<LayerBaseClient> getOwner() const;
 
     private:
-        virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
+        virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+                uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+        virtual status_t setBufferCount(int bufferCount);
+
         virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); 
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
@@ -366,20 +313,22 @@
     protected:
         friend class LayerBaseClient;
         sp<SurfaceFlinger>  mFlinger;
-        int32_t             mToken;
         int32_t             mIdentity;
         wp<LayerBaseClient> mOwner;
     };
 
     friend class Surface;
 
+protected:
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
 private:
-                int32_t         mIndex;
-    mutable     Mutex           mLock;
-    mutable     wp<Surface>     mClientSurface;
+    mutable Mutex mLock;
+    mutable wp<Surface> mClientSurface;
+    const wp<Client> mClientRef;
     // only read
-    const       uint32_t        mIdentity;
-    static      int32_t         sIdentity;
+    const uint32_t mIdentity;
+    static int32_t sIdentity;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp
index 5fd7904..2ee21b9 100644
--- a/services/surfaceflinger/LayerBlur.cpp
+++ b/services/surfaceflinger/LayerBlur.cpp
@@ -33,14 +33,9 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerBlur::typeInfo = LayerBaseClient::typeInfo | 8;
-const char* const LayerBlur::typeID = "LayerBlur";
-
-// ---------------------------------------------------------------------------
-
 LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client, int32_t i)
-    : LayerBaseClient(flinger, display, client, i), mCacheDirty(true),
+        const sp<Client>& client)
+    : LayerBaseClient(flinger, display, client), mCacheDirty(true),
           mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
           mWidthScale(1.0f), mHeightScale(1.0f),
           mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
@@ -100,7 +95,9 @@
                     mCacheDirty = false;
                 } else {
                     if (!mAutoRefreshPending) {
-                        mFlinger->signalDelayedEvent(ms2ns(500));
+                        mFlinger->postMessageAsync(
+                                new MessageBase(MessageQueue::INVALIDATE),
+                                ms2ns(500));
                         mAutoRefreshPending = true;
                     }
                 }
@@ -149,6 +146,11 @@
     Region::const_iterator it = clip.begin();
     Region::const_iterator const end = clip.end();
     if (it != end) {
+#if defined(GL_OES_texture_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
+        }
+#endif
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, mTextureName);
 
@@ -181,7 +183,7 @@
             bl.data = (GGLubyte*)pixels;            
             blurFilter(&bl, 8, 2);
 
-            if (mFlags & (DisplayHardware::NPOT_EXTENSION)) {
+            if (GLExtensions::getInstance().haveNpot()) {
                 glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
                         mReadFormat, mReadType, pixels);
                 mWidthScale  = 1.0f / w;
@@ -206,8 +208,8 @@
 
         const State& s = drawingState();
         if (UNLIKELY(s.alpha < 0xFF)) {
-            const GGLfixed alpha = (s.alpha << 16)/255;
-            glColor4x(0, 0, 0, alpha);
+            const GLfloat alpha = s.alpha * (1.0f/255.0f);
+            glColor4f(0, 0, 0, alpha);
             glEnable(GL_BLEND);
             glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
             glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -225,38 +227,22 @@
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
         glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 
-        if (UNLIKELY(transformed()
-                || !(mFlags & DisplayHardware::DRAW_TEXTURE_EXTENSION) )) {
-            // This is a very rare scenario.
-            glMatrixMode(GL_TEXTURE);
-            glLoadIdentity();
-            glScalef(mWidthScale, mHeightScale, 1);
-            glTranslatef(-x, mYOffset - y, 0);
-            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            glVertexPointer(2, GL_FIXED, 0, mVertices);
-            glTexCoordPointer(2, GL_FIXED, 0, mVertices);
-            while (it != end) {
-                const Rect& r = *it++;
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 
-            }       
-            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-        } else {
-            // NOTE: this is marginally faster with the software gl, because
-            // glReadPixels() reads the fb bottom-to-top, however we'll
-            // skip all the jaccobian computations.
-            Rect r;
-            GLint crop[4] = { 0, 0, w, h };
-            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
-            y = fbHeight - (y + h);
-            while (it != end) {
-                const Rect& r = *it++;
-                const GLint sy = fbHeight - (r.top + r.height());
-                glScissor(r.left, sy, r.width(), r.height());
-                glDrawTexiOES(x, y, 0, w, h);
-            }
+        glMatrixMode(GL_TEXTURE);
+        glLoadIdentity();
+        glScalef(mWidthScale, mHeightScale, 1);
+        glTranslatef(-x, mYOffset - y, 0);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+        glVertexPointer(2, GL_FLOAT, 0, mVertices);
+        glTexCoordPointer(2, GL_FLOAT, 0, mVertices);
+        while (it != end) {
+            const Rect& r = *it++;
+            const GLint sy = fbHeight - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
         }
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+        glLoadIdentity();
+        glMatrixMode(GL_MODELVIEW);
     }
 }
 
diff --git a/services/surfaceflinger/LayerBlur.h b/services/surfaceflinger/LayerBlur.h
index 5b63dec..4c9ec64 100644
--- a/services/surfaceflinger/LayerBlur.h
+++ b/services/surfaceflinger/LayerBlur.h
@@ -31,18 +31,14 @@
 class LayerBlur : public LayerBaseClient
 {
 public:    
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
                 LayerBlur(SurfaceFlinger* flinger, DisplayID display,
-                        const sp<Client>& client, int32_t i);
+                        const sp<Client>& client);
         virtual ~LayerBlur();
 
     virtual void onDraw(const Region& clip) const;
     virtual bool needsBlending() const  { return true; }
     virtual bool isSecure() const       { return false; }
+    virtual const char* getTypeId() const { return "LayerBlur"; }
 
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void setVisibleRegion(const Region& visibleRegion);
diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp
index 0869283..fdf9abc 100644
--- a/services/surfaceflinger/LayerBuffer.cpp
+++ b/services/surfaceflinger/LayerBuffer.cpp
@@ -39,15 +39,13 @@
 
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerBuffer::typeInfo = LayerBaseClient::typeInfo | 0x20;
-const char* const LayerBuffer::typeID = "LayerBuffer";
 gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
 
 // ---------------------------------------------------------------------------
 
 LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client, int32_t i)
-    : LayerBaseClient(flinger, display, client, i),
+        const sp<Client>& client)
+    : LayerBaseClient(flinger, display, client),
       mNeedsBlending(false), mBlitEngine(0)
 {
 }
@@ -62,8 +60,7 @@
 void LayerBuffer::onFirstRef()
 {
     LayerBaseClient::onFirstRef();
-    mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
-            const_cast<LayerBuffer *>(this));
+    mSurface = new SurfaceLayerBuffer(mFlinger, this);
 
     hw_module_t const* module = (hw_module_t const*)sGrallocModule;
     if (!module) {
@@ -120,7 +117,7 @@
         source->onTransaction(flags);
     uint32_t res = LayerBase::doTransaction(flags);
     // we always want filtering for these surfaces
-    mUseLinearFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG);
+    mNeedsFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG);
     return res;
 }
 
@@ -145,14 +142,6 @@
     }
 }
 
-bool LayerBuffer::transformed() const
-{
-    sp<Source> source(getSource());
-    if (LIKELY(source != 0))
-        return source->transformed();
-    return false;
-}
-
 void LayerBuffer::serverDestroy()
 {
     sp<Source> source(clearSource());
@@ -214,9 +203,9 @@
 // LayerBuffer::SurfaceLayerBuffer
 // ============================================================================
 
-LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
-        SurfaceID id, const sp<LayerBuffer>& owner)
-    : LayerBaseClient::Surface(flinger, id, owner->getIdentity(), owner)
+LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(
+        const sp<SurfaceFlinger>& flinger, const sp<LayerBuffer>& owner)
+    : LayerBaseClient::Surface(flinger, owner->getIdentity(), owner)
 {
 }
 
@@ -321,16 +310,12 @@
 }
 void LayerBuffer::Source::unregisterBuffers() {
 }
-bool LayerBuffer::Source::transformed() const {
-    return mLayer.mTransformed; 
-}
 
 // ---------------------------------------------------------------------------
 
 LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
         const ISurface::BufferHeap& buffers)
-    : Source(layer), mStatus(NO_ERROR), mBufferSize(0),
-      mUseEGLImageDirectly(true)
+    : Source(layer), mStatus(NO_ERROR), mBufferSize(0)
 {
     if (buffers.heap == NULL) {
         // this is allowed, but in this case, it is illegal to receive
@@ -388,11 +373,11 @@
 
     if (mTexture.name != -1U) {
         // GL textures can only be destroyed from the GL thread
-        mLayer.mFlinger->mEventQueue.postMessage(
-                new MessageDestroyTexture(mLayer.mFlinger.get(), mTexture.name) );
+        getFlinger()->mEventQueue.postMessage(
+                new MessageDestroyTexture(getFlinger(), mTexture.name) );
     }
     if (mTexture.image != EGL_NO_IMAGE_KHR) {
-        EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
+        EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
         eglDestroyImageKHR(dpy, mTexture.image);
     }
 }
@@ -444,11 +429,6 @@
     mBuffer = buffer;
 }
 
-bool LayerBuffer::BufferSource::transformed() const
-{
-    return mBufferHeap.transform ? true : Source::transformed(); 
-}
-
 void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
 {
     sp<Buffer> ourBuffer(getBuffer());
@@ -462,35 +442,10 @@
     NativeBuffer src(ourBuffer->getBuffer());
     const Rect transformedBounds(mLayer.getTransformedBounds());
 
-    if (UNLIKELY(mTexture.name == -1LU)) {
-        mTexture.name = mLayer.createTexture();
-    }
-
 #if defined(EGL_ANDROID_image_native_buffer)
-    if (mLayer.mFlags & DisplayHardware::DIRECT_TEXTURE) {
+    if (GLExtensions::getInstance().haveDirectTexture()) {
         err = INVALID_OPERATION;
         if (ourBuffer->supportsCopybit()) {
-
-            // there are constraints on buffers used by the GPU and these may not
-            // be honored here. We need to change the API so the buffers
-            // are allocated with gralloc. For now disable this code-path
-#if 0
-            // First, try to use the buffer as an EGLImage directly
-            if (mUseEGLImageDirectly) {
-                // NOTE: Assume the buffer is allocated with the proper USAGE flags
-
-                sp<GraphicBuffer> buffer = new  GraphicBuffer(
-                        src.img.w, src.img.h, src.img.format,
-                        GraphicBuffer::USAGE_HW_TEXTURE,
-                        src.img.w, src.img.handle, false);
-
-                err = mLayer.initializeEglImage(buffer, &mTexture);
-                if (err != NO_ERROR) {
-                    mUseEGLImageDirectly = false;
-                }
-            }
-#endif
-
             copybit_device_t* copybit = mLayer.mBlitEngine;
             if (copybit && err != NO_ERROR) {
                 // create our EGLImageKHR the first time
@@ -527,10 +482,10 @@
         t.format = src.img.format;
         t.data = (GGLubyte*)src.img.base;
         const Region dirty(Rect(t.width, t.height));
-        mLayer.loadTexture(&mTexture, dirty, t);
+        mTextureManager.loadTexture(&mTexture, dirty, t);
     }
 
-    mTexture.transform = mBufferHeap.transform;
+    mLayer.setBufferTransform(mBufferHeap.transform);
     mLayer.drawWithOpenGL(clip, mTexture);
 }
 
@@ -569,7 +524,7 @@
     // figure out if we need linear filtering
     if (buffers.w * h == buffers.h * w) {
         // same pixel area, don't use filtering
-        mLayer.mUseLinearFiltering = false;
+        mLayer.mNeedsFiltering = false;
     }
 
     // Allocate a temporary buffer and create the corresponding EGLImageKHR
@@ -593,7 +548,8 @@
         dst.crop.r = w;
         dst.crop.b = h;
 
-        err = mLayer.initializeEglImage(buffer, &mTexture);
+        EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
+        err = mTextureManager.initEglImage(&mTexture, dpy, buffer);
     }
 
     return err;
@@ -602,14 +558,13 @@
 void LayerBuffer::BufferSource::clearTempBufferImage() const
 {
     // delete the image
-    EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
+    EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
     eglDestroyImageKHR(dpy, mTexture.image);
 
     // and the associated texture (recreate a name)
     glDeleteTextures(1, &mTexture.name);
     Texture defaultTexture;
     mTexture = defaultTexture;
-    mTexture.name = mLayer.createTexture();
 }
 
 // ---------------------------------------------------------------------------
@@ -620,7 +575,7 @@
     : Source(layer), mVisibilityChanged(false),
     mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation)
 {
-    overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
+    overlay_control_device_t* overlay_dev = getFlinger()->getOverlayEngine();
     if (overlay_dev == NULL) {
         // overlays not supported
         return;
@@ -651,7 +606,7 @@
 
     *overlayRef = new OverlayRef(mOverlayHandle, channel,
             mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
-    mLayer.mFlinger->signalEvent();
+    getFlinger()->signalEvent();
 }
 
 LayerBuffer::OverlaySource::~OverlaySource()
@@ -665,9 +620,9 @@
 void LayerBuffer::OverlaySource::onDraw(const Region& clip) const
 {
     // this would be where the color-key would be set, should we need it.
-    GLclampx red = 0;
-    GLclampx green = 0;
-    GLclampx blue = 0;
+    GLclampf red = 0;
+    GLclampf green = 0;
+    GLclampf blue = 0;
     mLayer.clearWithOpenGL(clip, red, green, blue, 0);
 }
 
diff --git a/services/surfaceflinger/LayerBuffer.h b/services/surfaceflinger/LayerBuffer.h
index b176623..1c0bf83 100644
--- a/services/surfaceflinger/LayerBuffer.h
+++ b/services/surfaceflinger/LayerBuffer.h
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 
 #include "LayerBase.h"
+#include "TextureManager.h"
 
 struct copybit_device_t;
 
@@ -45,31 +46,26 @@
         virtual void onVisibilityResolved(const Transform& planeTransform);
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
-        virtual bool transformed() const;
         virtual void destroy() { }
+        SurfaceFlinger* getFlinger() const { return mLayer.mFlinger.get(); }
     protected:
         LayerBuffer& mLayer;
     };
 
 public:
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-
             LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
-                    const sp<Client>& client, int32_t i);
+                    const sp<Client>& client);
         virtual ~LayerBuffer();
 
     virtual void onFirstRef();
     virtual bool needsBlending() const;
+    virtual const char* getTypeId() const { return "LayerBuffer"; }
 
     virtual sp<LayerBaseClient::Surface> createSurface() const;
     virtual status_t ditch();
     virtual void onDraw(const Region& clip) const;
     virtual uint32_t doTransaction(uint32_t flags);
     virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-    virtual bool transformed() const;
 
     status_t registerBuffers(const ISurface::BufferHeap& buffers);
     void postBuffer(ssize_t offset);
@@ -133,7 +129,6 @@
         virtual void onDraw(const Region& clip) const;
         virtual void postBuffer(ssize_t offset);
         virtual void unregisterBuffers();
-        virtual bool transformed() const;
         virtual void destroy() { }
     private:
         status_t initTempBuffer() const;
@@ -143,9 +138,9 @@
         status_t                        mStatus;
         ISurface::BufferHeap            mBufferHeap;
         size_t                          mBufferSize;
-        mutable LayerBase::Texture      mTexture;
+        mutable Texture                 mTexture;
         mutable NativeBuffer            mTempBuffer;
-        mutable bool                    mUseEGLImageDirectly;
+        mutable TextureManager          mTextureManager;
     };
     
     class OverlaySource : public Source {
@@ -195,7 +190,7 @@
     {
     public:
         SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
-                        SurfaceID id, const sp<LayerBuffer>& owner);
+                        const sp<LayerBuffer>& owner);
         virtual ~SurfaceLayerBuffer();
 
         virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
index fd61e30..a1f339e 100644
--- a/services/surfaceflinger/LayerDim.cpp
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -30,9 +30,6 @@
 namespace android {
 // ---------------------------------------------------------------------------
 
-const uint32_t LayerDim::typeInfo = LayerBaseClient::typeInfo | 0x10;
-const char* const LayerDim::typeID = "LayerDim";
-
 bool LayerDim::sUseTexture;
 GLuint LayerDim::sTexId;
 EGLImageKHR LayerDim::sImage;
@@ -42,8 +39,8 @@
 // ---------------------------------------------------------------------------
 
 LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client, int32_t i)
-    : LayerBaseClient(flinger, display, client, i)
+        const sp<Client>& client)
+    : LayerBaseClient(flinger, display, client)
 {
 }
 
@@ -54,54 +51,6 @@
     sWidth = w;
     sHeight = h;
     sUseTexture = false;
-    
-#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
-
-#warning "using a texture to implement LayerDim"
-    
-    /* On some h/w like msm7K, it is faster to use a texture because the
-     * software renderer will defer to copybit, for this to work we need to
-     * use an EGLImage texture so copybit can actually make use of it.
-     * This burns a full-screen worth of graphic memory.
-     */
-
-    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
-    uint32_t flags = hw.getFlags();
-
-    if (LIKELY(flags & DisplayHardware::DIRECT_TEXTURE)) {
-        sp<GraphicBuffer> buffer = new GraphicBuffer(w, h, PIXEL_FORMAT_RGB_565,
-                 GraphicBuffer::USAGE_SW_WRITE_OFTEN |
-                 GraphicBuffer::USAGE_HW_TEXTURE);
-        
-        android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
-
-        glGenTextures(1, &sTexId);
-        glBindTexture(GL_TEXTURE_2D, sTexId);
-
-        EGLDisplay dpy = eglGetCurrentDisplay();
-        sImage = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, 
-                EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)clientBuf, 0);
-        if (sImage == EGL_NO_IMAGE_KHR) {
-            LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
-            return;
-        }
-
-        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)sImage);
-        GLint error = glGetError();
-        if (error != GL_NO_ERROR) {
-            eglDestroyImageKHR(dpy, sImage);
-            LOGE("glEGLImageTargetTexture2DOES() failed. err=0x%4x", error);
-            return;
-        }
-
-        // initialize the texture with zeros
-        GGLSurface t;
-        buffer->lock(&t, GRALLOC_USAGE_SW_WRITE_OFTEN);
-        memset(t.data, 0, t.stride * t.height * 2);
-        buffer->unlock();
-        sUseTexture = true;
-    }
-#endif
 }
 
 LayerDim::~LayerDim()
@@ -115,33 +64,19 @@
     Region::const_iterator const end = clip.end();
     if (s.alpha>0 && (it != end)) {
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
-        const GGLfixed alpha = (s.alpha << 16)/255;
+        const GLfloat alpha = s.alpha/255.0f;
         const uint32_t fbHeight = hw.getHeight();
         glDisable(GL_DITHER);
         glEnable(GL_BLEND);
         glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
-        glColor4x(0, 0, 0, alpha);
-        
-#if defined(DIM_WITH_TEXTURE) && defined(EGL_ANDROID_image_native_buffer)
-        if (sUseTexture) {
-            glBindTexture(GL_TEXTURE_2D, sTexId);
-            glEnable(GL_TEXTURE_2D);
-            glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-            const GLshort texCoords[4][2] = {
-                    { 0,  0 },
-                    { 0,  1 },
-                    { 1,  1 },
-                    { 1,  0 }
-            };
-            glMatrixMode(GL_TEXTURE);
-            glLoadIdentity();
-            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-            glTexCoordPointer(2, GL_SHORT, 0, texCoords);
-        } else
-#endif
-        {
-            glDisable(GL_TEXTURE_2D);
+        glColor4f(0, 0, 0, alpha);
+
+#if defined(GL_OES_texture_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
         }
+#endif
+        glDisable(GL_TEXTURE_2D);
 
         GLshort w = sWidth;
         GLshort h = sHeight;
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
index d4672a1..f032314 100644
--- a/services/surfaceflinger/LayerDim.h
+++ b/services/surfaceflinger/LayerDim.h
@@ -37,18 +37,14 @@
     static int32_t sWidth;
     static int32_t sHeight;
 public:    
-    static const uint32_t typeInfo;
-    static const char* const typeID;
-    virtual char const* getTypeID() const { return typeID; }
-    virtual uint32_t getTypeInfo() const { return typeInfo; }
-    
                 LayerDim(SurfaceFlinger* flinger, DisplayID display,
-                        const sp<Client>& client, int32_t i);
+                        const sp<Client>& client);
         virtual ~LayerDim();
 
     virtual void onDraw(const Region& clip) const;
     virtual bool needsBlending() const  { return true; }
     virtual bool isSecure() const       { return false; }
+    virtual const char* getTypeId() const { return "LayerDim"; }
 
     static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
 };
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
index b43d801..d668e88 100644
--- a/services/surfaceflinger/MessageQueue.cpp
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -60,9 +60,9 @@
 {
 }
 
-MessageList::value_type MessageQueue::waitMessage(nsecs_t timeout)
+sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout)
 {
-    MessageList::value_type result;
+    sp<MessageBase> result;
 
     bool again;
     do {
@@ -132,6 +132,7 @@
         if (again) {
             // the message has been processed. release our reference to it
             // without holding the lock.
+            result->notify();
             result = 0;
         }
         
@@ -141,7 +142,7 @@
 }
 
 status_t MessageQueue::postMessage(
-        const MessageList::value_type& message, nsecs_t relTime, uint32_t flags)
+        const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
 {
     return queueMessage(message, relTime, flags);
 }
@@ -154,7 +155,7 @@
 }
 
 status_t MessageQueue::queueMessage(
-        const MessageList::value_type& message, nsecs_t relTime, uint32_t flags)
+        const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
 {
     Mutex::Autolock _l(mLock);
     message->when = systemTime() + relTime;
@@ -167,13 +168,13 @@
     return NO_ERROR;
 }
 
-void MessageQueue::dump(const MessageList::value_type& message)
+void MessageQueue::dump(const sp<MessageBase>& message)
 {
     Mutex::Autolock _l(mLock);
     dumpLocked(message);
 }
 
-void MessageQueue::dumpLocked(const MessageList::value_type& message)
+void MessageQueue::dumpLocked(const sp<MessageBase>& message)
 {
     LIST::const_iterator cur(mMessages.begin());
     LIST::const_iterator end(mMessages.end());
diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
index dc8138d..890f809 100644
--- a/services/surfaceflinger/MessageQueue.h
+++ b/services/surfaceflinger/MessageQueue.h
@@ -25,6 +25,7 @@
 #include <utils/Timers.h>
 #include <utils/List.h>
 
+#include "Barrier.h"
 
 namespace android {
 
@@ -37,7 +38,6 @@
     List< sp<MessageBase> > mList;
     typedef List< sp<MessageBase> > LIST;
 public:
-    typedef sp<MessageBase> value_type;
     inline LIST::iterator begin()                { return mList.begin(); }
     inline LIST::const_iterator begin() const    { return mList.begin(); }
     inline LIST::iterator end()                  { return mList.end(); }
@@ -63,11 +63,19 @@
     
     // return true if message has a handler
     virtual bool handler() { return false; }
+
+    // waits for the handler to be processed
+    void wait() const { barrier.wait(); }
     
+    // releases all waiters. this is done automatically if
+    // handler returns true
+    void notify() const { barrier.open(); }
+
 protected:
     virtual ~MessageBase() { }
 
 private:
+    mutable Barrier barrier;
     friend class LightRefBase<MessageBase>;
 };
 
@@ -82,42 +90,33 @@
     typedef List< sp<MessageBase> > LIST;
 public:
 
-    // this is a work-around the multichar constant warning. A macro would
-    // work too, but would pollute the namespace.
-    template <int a, int b, int c, int d>
-    struct WHAT {
-        static const uint32_t Value = 
-            (uint32_t(a&0xff)<<24)|(uint32_t(b&0xff)<<16)|
-            (uint32_t(c&0xff)<<8)|uint32_t(d&0xff);
-    };
-    
     MessageQueue();
     ~MessageQueue();
 
     // pre-defined messages
     enum {
-        INVALIDATE = WHAT<'_','p','d','t'>::Value
+        INVALIDATE = '_upd'
     };
 
-    MessageList::value_type waitMessage(nsecs_t timeout = -1);
+    sp<MessageBase> waitMessage(nsecs_t timeout = -1);
     
-    status_t postMessage(const MessageList::value_type& message, 
+    status_t postMessage(const sp<MessageBase>& message,
             nsecs_t reltime=0, uint32_t flags = 0);
-        
+
     status_t invalidate();
     
-    void dump(const MessageList::value_type& message);
+    void dump(const sp<MessageBase>& message);
 
 private:
-    status_t queueMessage(const MessageList::value_type& message,
+    status_t queueMessage(const sp<MessageBase>& message,
             nsecs_t reltime, uint32_t flags);
-    void dumpLocked(const MessageList::value_type& message);
+    void dumpLocked(const sp<MessageBase>& message);
     
     Mutex           mLock;
     Condition       mCondition;
     MessageList     mMessages;
     bool            mInvalidate;
-    MessageList::value_type mInvalidateMessage;
+    sp<MessageBase> mInvalidateMessage;
 };
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0722fda..637ae48 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -44,6 +44,7 @@
 #include <GLES/gl.h>
 
 #include "clz.h"
+#include "GLExtensions.h"
 #include "Layer.h"
 #include "LayerBlur.h"
 #include "LayerBuffer.h"
@@ -62,111 +63,8 @@
 #define DISPLAY_COUNT       1
 
 namespace android {
-
 // ---------------------------------------------------------------------------
 
-void SurfaceFlinger::instantiate() {
-    defaultServiceManager()->addService(
-            String16("SurfaceFlinger"), new SurfaceFlinger());
-}
-
-void SurfaceFlinger::shutdown() {
-    // we should unregister here, but not really because
-    // when (if) the service manager goes away, all the services
-    // it has a reference to will leave too.
-}
-
-// ---------------------------------------------------------------------------
-
-SurfaceFlinger::LayerVector::LayerVector(const SurfaceFlinger::LayerVector& rhs)
-    : lookup(rhs.lookup), layers(rhs.layers)
-{
-}
-
-ssize_t SurfaceFlinger::LayerVector::indexOf(
-        const sp<LayerBase>& key, size_t guess) const
-{
-    if (guess<size() && lookup.keyAt(guess) == key)
-        return guess;
-    const ssize_t i = lookup.indexOfKey(key);
-    if (i>=0) {
-        const size_t idx = lookup.valueAt(i);
-        LOGE_IF(layers[idx]!=key,
-            "LayerVector[%p]: layers[%d]=%p, key=%p",
-            this, int(idx), layers[idx].get(), key.get());
-        return idx;
-    }
-    return i;
-}
-
-ssize_t SurfaceFlinger::LayerVector::add(
-        const sp<LayerBase>& layer,
-        Vector< sp<LayerBase> >::compar_t cmp)
-{
-    size_t count = layers.size();
-    ssize_t l = 0;
-    ssize_t h = count-1;
-    ssize_t mid;
-    sp<LayerBase> const* a = layers.array();
-    while (l <= h) {
-        mid = l + (h - l)/2;
-        const int c = cmp(a+mid, &layer);
-        if (c == 0)     { l = mid; break; }
-        else if (c<0)   { l = mid+1; }
-        else            { h = mid-1; }
-    }
-    size_t order = l;
-    while (order<count && !cmp(&layer, a+order)) {
-        order++;
-    }
-    count = lookup.size();
-    for (size_t i=0 ; i<count ; i++) {
-        if (lookup.valueAt(i) >= order) {
-            lookup.editValueAt(i)++;
-        }
-    }
-    layers.insertAt(layer, order);
-    lookup.add(layer, order);
-    return order;
-}
-
-ssize_t SurfaceFlinger::LayerVector::remove(const sp<LayerBase>& layer)
-{
-    const ssize_t keyIndex = lookup.indexOfKey(layer);
-    if (keyIndex >= 0) {
-        const size_t index = lookup.valueAt(keyIndex);
-        LOGE_IF(layers[index]!=layer,
-                "LayerVector[%p]: layers[%u]=%p, layer=%p",
-                this, int(index), layers[index].get(), layer.get());
-        layers.removeItemsAt(index);
-        lookup.removeItemsAt(keyIndex);
-        const size_t count = lookup.size();
-        for (size_t i=0 ; i<count ; i++) {
-            if (lookup.valueAt(i) >= size_t(index)) {
-                lookup.editValueAt(i)--;
-            }
-        }
-        return index;
-    }
-    return NAME_NOT_FOUND;
-}
-
-ssize_t SurfaceFlinger::LayerVector::reorder(
-        const sp<LayerBase>& layer,
-        Vector< sp<LayerBase> >::compar_t cmp)
-{
-    // XXX: it's a little lame. but oh well...
-    ssize_t err = remove(layer);
-    if (err >=0)
-        err = add(layer, cmp);
-    return err;
-}
-
-// ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
-
 SurfaceFlinger::SurfaceFlinger()
     :   BnSurfaceComposer(), Thread(false),
         mTransactionFlags(0),
@@ -206,8 +104,8 @@
     property_get("debug.sf.showbackground", value, "0");
     mDebugBackground = atoi(value);
 
-    LOGI_IF(mDebugRegion,           "showupdates enabled");
-    LOGI_IF(mDebugBackground,       "showbackground enabled");
+    LOGI_IF(mDebugRegion,       "showupdates enabled");
+    LOGI_IF(mDebugBackground,   "showbackground enabled");
 }
 
 SurfaceFlinger::~SurfaceFlinger()
@@ -225,56 +123,29 @@
     return mServerHeap;
 }
 
-sp<ISurfaceFlingerClient> SurfaceFlinger::createConnection()
+sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
 {
-    Mutex::Autolock _l(mStateLock);
-    uint32_t token = mTokens.acquire();
-
-    sp<Client> client = new Client(token, this);
-    if (client->ctrlblk == 0) {
-        mTokens.release(token);
-        return 0;
+    sp<ISurfaceComposerClient> bclient;
+    sp<Client> client(new Client(this));
+    status_t err = client->initCheck();
+    if (err == NO_ERROR) {
+        bclient = client;
     }
-    status_t err = mClientsMap.add(token, client);
-    if (err < 0) {
-        mTokens.release(token);
-        return 0;
-    }
-    sp<BClient> bclient =
-        new BClient(this, token, client->getControlBlockMemory());
     return bclient;
 }
 
-void SurfaceFlinger::destroyConnection(ClientID cid)
+sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
 {
-    Mutex::Autolock _l(mStateLock);
-    sp<Client> client = mClientsMap.valueFor(cid);
-    if (client != 0) {
-        // free all the layers this client owns
-        Vector< wp<LayerBaseClient> > layers(client->getLayers());
-        const size_t count = layers.size();
-        for (size_t i=0 ; i<count ; i++) {
-            sp<LayerBaseClient> layer(layers[i].promote());
-            if (layer != 0) {
-                purgatorizeLayer_l(layer);
-            }
-        }
-
-        // the resources associated with this client will be freed
-        // during the next transaction, after these surfaces have been
-        // properly removed from the screen
-
-        // remove this client from our ClientID->Client mapping.
-        mClientsMap.removeItem(cid);
-
-        // and add it to the list of disconnected clients
-        mDisconnectedClients.add(client);
-
-        // request a transaction
-        setTransactionFlags(eTransactionNeeded);
+    sp<ISurfaceComposerClient> bclient;
+    sp<UserClient> client(new UserClient(this));
+    status_t err = client->initCheck();
+    if (err == NO_ERROR) {
+        bclient = client;
     }
+    return bclient;
 }
 
+
 const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
 {
     LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
@@ -357,16 +228,8 @@
     dcblk->ydpi         = hw.getDpiY();
     dcblk->fps          = hw.getRefreshRate();
     dcblk->density      = hw.getDensity();
-    asm volatile ("":::"memory");
 
     // Initialize OpenGL|ES
-    glActiveTexture(GL_TEXTURE0);
-    glBindTexture(GL_TEXTURE_2D, 0);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
     glPixelStorei(GL_PACK_ALIGNMENT, 4); 
     glEnableClientState(GL_VERTEX_ARRAY);
@@ -427,7 +290,7 @@
             timeout = waitTime>0 ? waitTime : 0;
         }
 
-        MessageList::value_type msg = mEventQueue.waitMessage(timeout);
+        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
 
         // see if we timed out
         if (isFrozen()) {
@@ -462,9 +325,20 @@
     const_cast<SurfaceFlinger*>(this)->signalEvent();
 }
 
-void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
+status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags)
 {
-    mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay);
+    return mEventQueue.postMessage(msg, reltime, flags);
+}
+
+status_t SurfaceFlinger::postMessageSync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags)
+{
+    status_t res = mEventQueue.postMessage(msg, reltime, flags);
+    if (res == NO_ERROR) {
+        msg->wait();
+    }
+    return res;
 }
 
 // ----------------------------------------------------------------------------
@@ -558,6 +432,10 @@
 {
     Vector< sp<LayerBase> > ditchedLayers;
 
+    /*
+     * Perform and commit the transaction
+     */
+
     { // scope for the lock
         Mutex::Autolock _l(mStateLock);
         const nsecs_t now = systemTime();
@@ -565,9 +443,13 @@
         handleTransactionLocked(transactionFlags, ditchedLayers);
         mLastTransactionTime = systemTime() - now;
         mDebugInTransaction = 0;
+        // here the transaction has been committed
     }
 
-    // do this without lock held
+    /*
+     * Clean-up all layers that went away
+     * (do this without the lock held)
+     */
     const size_t count = ditchedLayers.size();
     for (size_t i=0 ; i<count ; i++) {
         if (ditchedLayers[i] != 0) {
@@ -655,10 +537,6 @@
                 }
             }
         }
-
-        // get rid of all resources we don't need anymore
-        // (layers and clients)
-        free_resources_l();
     }
 
     commitTransaction();
@@ -805,7 +683,8 @@
 void SurfaceFlinger::handlePageFlip()
 {
     bool visibleRegions = mVisibleRegionsDirty;
-    LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
+    LayerVector& currentLayers = const_cast<LayerVector&>(
+            mDrawingState.layersSortedByZ);
     visibleRegions |= lockPageFlip(currentLayers);
 
         const DisplayHardware& hw = graphicPlane(0).displayHardware();
@@ -813,6 +692,19 @@
         if (visibleRegions) {
             Region opaqueRegion;
             computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
+
+            /*
+             *  rebuild the visible layer list
+             */
+            mVisibleLayersSortedByZ.clear();
+            const LayerVector& currentLayers(mDrawingState.layersSortedByZ);
+            size_t count = currentLayers.size();
+            mVisibleLayersSortedByZ.setCapacity(count);
+            for (size_t i=0 ; i<count ; i++) {
+                if (!currentLayers[i]->visibleRegionScreen.isEmpty())
+                    mVisibleLayersSortedByZ.add(currentLayers[i]);
+            }
+
             mWormholeRegion = screenRegion.subtract(opaqueRegion);
             mVisibleRegionsDirty = false;
         }
@@ -827,7 +719,7 @@
     size_t count = currentLayers.size();
     sp<LayerBase> const* layers = currentLayers.array();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer = layers[i];
+        const sp<LayerBase>& layer(layers[i]);
         layer->lockPageFlip(recomputeVisibleRegions);
     }
     return recomputeVisibleRegions;
@@ -840,7 +732,7 @@
     size_t count = currentLayers.size();
     sp<LayerBase> const* layers = currentLayers.array();
     for (size_t i=0 ; i<count ; i++) {
-        const sp<LayerBase>& layer = layers[i];
+        const sp<LayerBase>& layer(layers[i]);
         layer->unlockPageFlip(planeTransform, mDirtyRegion);
     }
 }
@@ -872,7 +764,7 @@
         // takes a rectangle, we must make sure to update that whole
         // rectangle in that case
         if (flags & DisplayHardware::SWAP_RECTANGLE) {
-            // FIXME: we really should be able to pass a region to
+            // TODO: we really should be able to pass a region to
             // SWAP_RECTANGLE so that we don't have to redraw all this.
             mDirtyRegion.set(mInvalidRegion.bounds());
         } else {
@@ -909,18 +801,13 @@
         // draw something...
         drawWormhole();
     }
-    const SurfaceFlinger& flinger(*this);
-    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
-    const size_t count = drawingLayers.size();
-    sp<LayerBase> const* const layers = drawingLayers.array();
+    const Vector< sp<LayerBase> >& layers(mVisibleLayersSortedByZ);
+    const size_t count = layers.size();
     for (size_t i=0 ; i<count ; ++i) {
-        const sp<LayerBase>& layer = layers[i];
-        const Region& visibleRegion(layer->visibleRegionScreen);
-        if (!visibleRegion.isEmpty())  {
-            const Region clip(dirty.intersect(visibleRegion));
-            if (!clip.isEmpty()) {
-                layer->draw(clip);
-            }
+        const sp<LayerBase>& layer(layers[i]);
+        const Region clip(dirty.intersect(layer->visibleRegionScreen));
+        if (!clip.isEmpty()) {
+            layer->draw(clip);
         }
     }
 }
@@ -938,17 +825,18 @@
 
 void SurfaceFlinger::debugFlashRegions()
 {
-     const DisplayHardware& hw(graphicPlane(0).displayHardware());
-     const uint32_t flags = hw.getFlags();
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t flags = hw.getFlags();
 
-     if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
-             (flags & DisplayHardware::BUFFER_PRESERVED))) {
-         const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
-                 mDirtyRegion.bounds() : hw.bounds());
-         composeSurfaces(repaint);
-     }
-    
-    glDisable(GL_TEXTURE_2D);
+    if (!((flags & DisplayHardware::SWAP_RECTANGLE) ||
+            (flags & DisplayHardware::BUFFER_PRESERVED))) {
+        const Region repaint((flags & DisplayHardware::PARTIAL_UPDATES) ?
+                mDirtyRegion.bounds() : hw.bounds());
+        composeSurfaces(repaint);
+    }
+
+    TextureManager::deactivateTextures();
+
     glDisable(GL_BLEND);
     glDisable(GL_DITHER);
     glDisable(GL_SCISSOR_TEST);
@@ -956,9 +844,9 @@
     static int toggle = 0;
     toggle = 1 - toggle;
     if (toggle) {
-        glColor4x(0x10000, 0, 0x10000, 0x10000);
+        glColor4f(1, 0, 1, 1);
     } else {
-        glColor4x(0x10000, 0x10000, 0, 0x10000);
+        glColor4f(1, 1, 0, 1);
     }
 
     Region::const_iterator it = mDirtyRegion.begin();
@@ -974,7 +862,7 @@
         glVertexPointer(2, GL_FLOAT, 0, vertices);
         glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
     }
-    
+
     if (mInvalidRegion.isEmpty()) {
         mDirtyRegion.dump("mDirtyRegion");
         mInvalidRegion.dump("mInvalidRegion");
@@ -982,7 +870,7 @@
     hw.flip(mInvalidRegion);
 
     if (mDebugRegion > 1)
-       usleep(mDebugRegion * 1000);
+        usleep(mDebugRegion * 1000);
 
     glEnable(GL_SCISSOR_TEST);
     //mDirtyRegion.dump("mDirtyRegion");
@@ -1002,7 +890,7 @@
     glDisable(GL_DITHER);
 
     if (LIKELY(!mDebugBackground)) {
-        glClearColorx(0,0,0,0);
+        glClearColor(0,0,0,0);
         Region::const_iterator it = region.begin();
         Region::const_iterator const end = region.end();
         while (it != end) {
@@ -1018,6 +906,11 @@
         glVertexPointer(2, GL_SHORT, 0, vertices);
         glTexCoordPointer(2, GL_SHORT, 0, tcoords);
         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#if defined(GL_OES_texture_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
+        }
+#endif
         glEnable(GL_TEXTURE_2D);
         glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
         glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
@@ -1061,6 +954,26 @@
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
+{
+    ssize_t i = mCurrentState.layersSortedByZ.add(layer);
+    return (i < 0) ? status_t(i) : status_t(NO_ERROR);
+}
+
+ssize_t SurfaceFlinger::addClientLayer(const sp<Client>& client,
+        const sp<LayerBaseClient>& lbc)
+{
+    Mutex::Autolock _l(mStateLock);
+
+    // attach this layer to the client
+    ssize_t name = client->attachLayer(lbc);
+
+    // add this layer to the current state list
+    addLayer_l(lbc);
+
+    return name;
+}
+
 status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
 {
     Mutex::Autolock _l(mStateLock);
@@ -1070,36 +983,15 @@
     return err;
 }
 
-status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
-{
-    layer->forceVisibilityTransaction();
-    setTransactionFlags(eTraversalNeeded);
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::addLayer_l(const sp<LayerBase>& layer)
-{
-    if (layer == 0)
-        return BAD_VALUE;
-    ssize_t i = mCurrentState.layersSortedByZ.add(
-                layer, &LayerBase::compareCurrentStateZ);
-    sp<LayerBaseClient> lbc = LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
-    if (lbc != 0) {
-        mLayerMap.add(lbc->serverIndex(), lbc);
-    }
-    return NO_ERROR;
-}
-
 status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
 {
+    sp<LayerBaseClient> lbc(layerBase->getLayerBaseClient());
+    if (lbc != 0) {
+        mLayerMap.removeItem( lbc->getSurface()->asBinder() );
+    }
     ssize_t index = mCurrentState.layersSortedByZ.remove(layerBase);
     if (index >= 0) {
         mLayersRemoved = true;
-        sp<LayerBaseClient> layer =
-            LayerBase::dynamicCast< LayerBaseClient* >(layerBase.get());
-        if (layer != 0) {
-            mLayerMap.removeItem(layer->serverIndex());
-        }
         return NO_ERROR;
     }
     return status_t(index);
@@ -1114,22 +1006,16 @@
 
     // it's possible that we don't find a layer, because it might
     // have been destroyed already -- this is not technically an error
-    // from the user because there is a race between BClient::destroySurface(),
-    // ~BClient() and ~ISurface().
+    // from the user because there is a race between Client::destroySurface(),
+    // ~Client() and ~ISurface().
     return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
 }
 
-
-void SurfaceFlinger::free_resources_l()
+status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
 {
-    // free resources associated with disconnected clients
-    Vector< sp<Client> >& disconnectedClients(mDisconnectedClients);
-    const size_t count = disconnectedClients.size();
-    for (size_t i=0 ; i<count ; i++) {
-        sp<Client> client = disconnectedClients[i];
-        mTokens.release(client->cid);
-    }
-    disconnectedClients.clear();
+    layer->forceVisibilityTransaction();
+    setTransactionFlags(eTraversalNeeded);
+    return NO_ERROR;
 }
 
 uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
@@ -1137,15 +1023,11 @@
     return android_atomic_and(~flags, &mTransactionFlags) & flags;
 }
 
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
+uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
 {
     uint32_t old = android_atomic_or(flags, &mTransactionFlags);
     if ((old & flags)==0) { // wake the server up
-        if (delay > 0) {
-            signalDelayedEvent(delay);
-        } else {
-            signalEvent();
-        }
+        signalEvent();
     }
     return old;
 }
@@ -1224,8 +1106,8 @@
     return orientation;
 }
 
-sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
-        const String8& name, ISurfaceFlingerClient::surface_data_t* params,
+sp<ISurface> SurfaceFlinger::createSurface(const sp<Client>& client, int pid,
+        const String8& name, ISurfaceComposerClient::surface_data_t* params,
         DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
         uint32_t flags)
 {
@@ -1238,57 +1120,52 @@
         return surfaceHandle;
     }
     
-    Mutex::Autolock _l(mStateLock);
-    sp<Client> client = mClientsMap.valueFor(clientId);
-    if (UNLIKELY(client == 0)) {
-        LOGE("createSurface() failed, client not found (id=%d)", clientId);
-        return surfaceHandle;
-    }
-
     //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
-    int32_t id = client->generateId(pid);
-    if (uint32_t(id) >= NUM_LAYERS_MAX) {
-        LOGE("createSurface() failed, generateId = %d", id);
-        return surfaceHandle;
-    }
-
+    sp<Layer> normalLayer;
     switch (flags & eFXSurfaceMask) {
         case eFXSurfaceNormal:
             if (UNLIKELY(flags & ePushBuffers)) {
-                layer = createPushBuffersSurfaceLocked(client, d, id,
-                        w, h, flags);
+                layer = createPushBuffersSurface(client, d, w, h, flags);
             } else {
-                layer = createNormalSurfaceLocked(client, d, id,
-                        w, h, flags, format);
+                normalLayer = createNormalSurface(client, d, w, h, flags, format);
+                layer = normalLayer;
             }
             break;
         case eFXSurfaceBlur:
-            layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
+            layer = createBlurSurface(client, d, w, h, flags);
             break;
         case eFXSurfaceDim:
-            layer = createDimSurfaceLocked(client, d, id, w, h, flags);
+            layer = createDimSurface(client, d, w, h, flags);
             break;
     }
 
     if (layer != 0) {
+        layer->initStates(w, h, flags);
         layer->setName(name);
-        setTransactionFlags(eTransactionNeeded);
+        ssize_t token = addClientLayer(client, layer);
+
         surfaceHandle = layer->getSurface();
         if (surfaceHandle != 0) { 
-            params->token = surfaceHandle->getToken();
+            params->token = token;
             params->identity = surfaceHandle->getIdentity();
             params->width = w;
             params->height = h;
             params->format = format;
+            if (normalLayer != 0) {
+                Mutex::Autolock _l(mStateLock);
+                mLayerMap.add(surfaceHandle->asBinder(), normalLayer);
+            }
         }
+
+        setTransactionFlags(eTransactionNeeded);
     }
 
     return surfaceHandle;
 }
 
-sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
+sp<Layer> SurfaceFlinger::createNormalSurface(
         const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags,
+        uint32_t w, uint32_t h, uint32_t flags,
         PixelFormat& format)
 {
     // initialize the surfaces
@@ -1298,53 +1175,56 @@
         format = PIXEL_FORMAT_RGBA_8888;
         break;
     case PIXEL_FORMAT_OPAQUE:
+#ifdef NO_RGBX_8888
         format = PIXEL_FORMAT_RGB_565;
+#else
+        format = PIXEL_FORMAT_RGBX_8888;
+#endif
         break;
     }
 
-    sp<Layer> layer = new Layer(this, display, client, id);
+#ifdef NO_RGBX_8888
+    if (format == PIXEL_FORMAT_RGBX_8888)
+        format = PIXEL_FORMAT_RGBA_8888;
+#endif
+
+    sp<Layer> layer = new Layer(this, display, client);
     status_t err = layer->setBuffers(w, h, format, flags);
-    if (LIKELY(err == NO_ERROR)) {
-        layer->initStates(w, h, flags);
-        addLayer_l(layer);
-    } else {
+    if (LIKELY(err != NO_ERROR)) {
         LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
         layer.clear();
     }
     return layer;
 }
 
-sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
+sp<LayerBlur> SurfaceFlinger::createBlurSurface(
         const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+        uint32_t w, uint32_t h, uint32_t flags)
 {
-    sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
+    sp<LayerBlur> layer = new LayerBlur(this, display, client);
     layer->initStates(w, h, flags);
-    addLayer_l(layer);
     return layer;
 }
 
-sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
+sp<LayerDim> SurfaceFlinger::createDimSurface(
         const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+        uint32_t w, uint32_t h, uint32_t flags)
 {
-    sp<LayerDim> layer = new LayerDim(this, display, client, id);
+    sp<LayerDim> layer = new LayerDim(this, display, client);
     layer->initStates(w, h, flags);
-    addLayer_l(layer);
     return layer;
 }
 
-sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
+sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
         const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
+        uint32_t w, uint32_t h, uint32_t flags)
 {
-    sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
+    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
     layer->initStates(w, h, flags);
-    addLayer_l(layer);
     return layer;
 }
 
-status_t SurfaceFlinger::removeSurface(SurfaceID index)
+status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
 {
     /*
      * called by the window manager, when a surface should be marked for
@@ -1357,7 +1237,7 @@
 
     status_t err = NAME_NOT_FOUND;
     Mutex::Autolock _l(mStateLock);
-    sp<LayerBaseClient> layer = getLayerUser_l(index);
+    sp<LayerBaseClient> layer = client->getLayerUser(sid);
     if (layer != 0) {
         err = purgatorizeLayer_l(layer);
         if (err == NO_ERROR) {
@@ -1397,21 +1277,20 @@
         }
     };
 
-    mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
+    postMessageAsync( new MessageDestroySurface(this, layer) );
     return NO_ERROR;
 }
 
 status_t SurfaceFlinger::setClientState(
-        ClientID cid,
+        const sp<Client>& client,
         int32_t count,
         const layer_state_t* states)
 {
     Mutex::Autolock _l(mStateLock);
     uint32_t flags = 0;
-    cid <<= 16;
     for (int i=0 ; i<count ; i++) {
-        const layer_state_t& s = states[i];
-        sp<LayerBaseClient> layer(getLayerUser_l(s.surface | cid));
+        const layer_state_t& s(states[i]);
+        sp<LayerBaseClient> layer(client->getLayerUser(s.surface));
         if (layer != 0) {
             const uint32_t what = s.what;
             if (what & ePositionChanged) {
@@ -1419,9 +1298,10 @@
                     flags |= eTraversalNeeded;
             }
             if (what & eLayerChanged) {
+                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
                 if (layer->setLayer(s.z)) {
-                    mCurrentState.layersSortedByZ.reorder(
-                            layer, &Layer::compareCurrentStateZ);
+                    mCurrentState.layersSortedByZ.removeAt(idx);
+                    mCurrentState.layersSortedByZ.add(layer);
                     // we need traversal (state changed)
                     // AND transaction (list changed)
                     flags |= eTransactionNeeded|eTraversalNeeded;
@@ -1457,12 +1337,6 @@
     return NO_ERROR;
 }
 
-sp<LayerBaseClient> SurfaceFlinger::getLayerUser_l(SurfaceID s) const
-{
-    sp<LayerBaseClient> layer = mLayerMap.valueFor(s);
-    return layer;
-}
-
 void SurfaceFlinger::screenReleased(int dpy)
 {
     // this may be called by a signal handler, we can't do too much in here
@@ -1512,83 +1386,17 @@
             result.append(buffer);
         }
 
-        size_t s = mClientsMap.size();
-        char name[64];
-        for (size_t i=0 ; i<s ; i++) {
-            sp<Client> client = mClientsMap.valueAt(i);
-            sprintf(name, "  Client (id=0x%08x)", client->cid);
-            client->dump(name);
-        }
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
         for (size_t i=0 ; i<count ; i++) {
-            /*** LayerBase ***/
-            const sp<LayerBase>& layer = currentLayers[i];
-            const Layer::State& s = layer->drawingState();
-            snprintf(buffer, SIZE,
-                    "+ %s %p\n"
-                    "      "
-                    "z=%9d, pos=(%4d,%4d), size=(%4d,%4d), "
-                    "needsBlending=%1d, needsDithering=%1d, invalidate=%1d, "
-                    "alpha=0x%02x, flags=0x%08x, tr=[%.2f, %.2f][%.2f, %.2f]\n",
-                    layer->getTypeID(), layer.get(),
-                    s.z, layer->tx(), layer->ty(), s.w, s.h,
-                    layer->needsBlending(), layer->needsDithering(),
-                    layer->contentDirty,
-                    s.alpha, s.flags,
-                    s.transform[0][0], s.transform[0][1],
-                    s.transform[1][0], s.transform[1][1]);
-            result.append(buffer);
-            buffer[0] = 0;
-            /*** LayerBaseClient ***/
-            sp<LayerBaseClient> lbc =
-                LayerBase::dynamicCast< LayerBaseClient* >(layer.get());
-            if (lbc != 0) {
-                sp<Client> client(lbc->client.promote());
-                snprintf(buffer, SIZE,
-                        "      name=%s\n", lbc->getName().string());
-                result.append(buffer);
-                snprintf(buffer, SIZE,
-                        "      id=0x%08x, client=0x%08x, identity=%u\n",
-                        lbc->clientIndex(), client.get() ? client->cid : 0,
-                        lbc->getIdentity());
-
-                result.append(buffer);
-                buffer[0] = 0;
-            }
-            /*** Layer ***/
-            sp<Layer> l = LayerBase::dynamicCast< Layer* >(layer.get());
-            if (l != 0) {
-                SharedBufferStack::Statistics stats = l->lcblk->getStats();
-                result.append( l->lcblk->dump("      ") );
-                sp<const GraphicBuffer> buf0(l->getBuffer(0));
-                sp<const GraphicBuffer> buf1(l->getBuffer(1));
-                uint32_t w0=0, h0=0, s0=0;
-                uint32_t w1=0, h1=0, s1=0;
-                if (buf0 != 0) {
-                    w0 = buf0->getWidth();
-                    h0 = buf0->getHeight();
-                    s0 = buf0->getStride();
-                }
-                if (buf1 != 0) {
-                    w1 = buf1->getWidth();
-                    h1 = buf1->getHeight();
-                    s1 = buf1->getStride();
-                }
-                snprintf(buffer, SIZE,
-                        "      "
-                        "format=%2d, [%3ux%3u:%3u] [%3ux%3u:%3u],"
-                        " freezeLock=%p, dq-q-time=%u us\n",
-                        l->pixelFormat(),
-                        w0, h0, s0, w1, h1, s1,
-                        l->getFreezeLock().get(), stats.totalTime);
-                result.append(buffer);
-                buffer[0] = 0;
-            }
+            const sp<LayerBase>& layer(currentLayers[i]);
+            layer->dump(result, buffer, SIZE);
+            const Layer::State& s(layer->drawingState());
             s.transparentRegion.dump(result, "transparentRegion");
             layer->transparentRegionScreen.dump(result, "transparentRegionScreen");
             layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
         }
+
         mWormholeRegion.dump(result, "WormholeRegion");
         const DisplayHardware& hw(graphicPlane(0).displayHardware());
         snprintf(buffer, SIZE,
@@ -1601,18 +1409,19 @@
                 "  last transaction time     : %f us\n",
                 mLastSwapBufferTime/1000.0, mLastTransactionTime/1000.0);
         result.append(buffer);
+
         if (inSwapBuffersDuration || !locked) {
             snprintf(buffer, SIZE, "  eglSwapBuffers time: %f us\n",
                     inSwapBuffersDuration/1000.0);
             result.append(buffer);
         }
+
         if (inTransactionDuration || !locked) {
             snprintf(buffer, SIZE, "  transaction time: %f us\n",
                     inTransactionDuration/1000.0);
             result.append(buffer);
         }
-        snprintf(buffer, SIZE, "  client count: %d\n", mClientsMap.size());
-        result.append(buffer);
+
         const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
         alloc.dump(result);
 
@@ -1705,12 +1514,91 @@
 }
 
 // ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
 
-Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
-    : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
+sp<Layer> SurfaceFlinger::getLayer(const sp<ISurface>& sur) const
+{
+    sp<Layer> result;
+    Mutex::Autolock _l(mStateLock);
+    result = mLayerMap.valueFor( sur->asBinder() ).promote();
+    return result;
+}
+
+// ---------------------------------------------------------------------------
+
+Client::Client(const sp<SurfaceFlinger>& flinger)
+    : mFlinger(flinger), mNameGenerator(1)
+{
+}
+
+Client::~Client()
+{
+    const size_t count = mLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        sp<LayerBaseClient> layer(mLayers.valueAt(i).promote());
+        if (layer != 0) {
+            mFlinger->removeLayer(layer);
+        }
+    }
+}
+
+status_t Client::initCheck() const {
+    return NO_ERROR;
+}
+
+ssize_t Client::attachLayer(const sp<LayerBaseClient>& layer)
+{
+    int32_t name = android_atomic_inc(&mNameGenerator);
+    mLayers.add(name, layer);
+    return name;
+}
+
+void Client::detachLayer(const LayerBaseClient* layer)
+{
+    // we do a linear search here, because this doesn't happen often
+    const size_t count = mLayers.size();
+    for (size_t i=0 ; i<count ; i++) {
+        if (mLayers.valueAt(i) == layer) {
+            mLayers.removeItemsAt(i, 1);
+            break;
+        }
+    }
+}
+sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
+    sp<LayerBaseClient> lbc;
+    const wp<LayerBaseClient>& layer(mLayers.valueFor(i));
+    if (layer != 0) {
+        lbc = layer.promote();
+        LOGE_IF(lbc==0, "getLayerUser(name=%d) is dead", int(i));
+    }
+    return lbc;
+}
+
+sp<IMemoryHeap> Client::getControlBlock() const {
+    return 0;
+}
+ssize_t Client::getTokenForSurface(const sp<ISurface>& sur) const {
+    return -1;
+}
+sp<ISurface> Client::createSurface(
+        ISurfaceComposerClient::surface_data_t* params, int pid,
+        const String8& name,
+        DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
+        uint32_t flags)
+{
+    return mFlinger->createSurface(this, pid, name, params,
+            display, w, h, format, flags);
+}
+status_t Client::destroySurface(SurfaceID sid) {
+    return mFlinger->removeSurface(this, sid);
+}
+status_t Client::setState(int32_t count, const layer_state_t* states) {
+    return mFlinger->setClientState(this, count, states);
+}
+
+// ---------------------------------------------------------------------------
+
+UserClient::UserClient(const sp<SurfaceFlinger>& flinger)
+    : ctrlblk(0), mBitmap(0), mFlinger(flinger)
 {
     const int pgsize = getpagesize();
     const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
@@ -1724,97 +1612,91 @@
     }
 }
 
-Client::~Client() {
+UserClient::~UserClient()
+{
     if (ctrlblk) {
         ctrlblk->~SharedClient();  // destroy our shared-structure.
     }
+
+    /*
+     * When a UserClient dies, it's unclear what to do exactly.
+     * We could go ahead and destroy all surfaces linked to that client
+     * however, it wouldn't be fair to the main Client
+     * (usually the the window-manager), which might want to re-target
+     * the layer to another UserClient.
+     * I think the best is to do nothing, or not much; in most cases the
+     * WM itself will go ahead and clean things up when it detects a client of
+     * his has died.
+     * The remaining question is what to display? currently we keep
+     * just keep the current buffer.
+     */
 }
 
-int32_t Client::generateId(int pid)
-{
-    const uint32_t i = clz( ~mBitmap );
-    if (i >= NUM_LAYERS_MAX) {
-        return NO_MEMORY;
-    }
-    mPid = pid;
-    mInUse.add(uint8_t(i));
-    mBitmap |= 1<<(31-i);
-    return i;
+status_t UserClient::initCheck() const {
+    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
 }
 
-status_t Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
+void UserClient::detachLayer(const Layer* layer)
 {
-    ssize_t idx = mInUse.indexOf(id);
-    if (idx < 0)
-        return NAME_NOT_FOUND;
-    return mLayers.insertAt(layer, idx);
-}
-
-void Client::free(int32_t id)
-{
-    ssize_t idx = mInUse.remove(uint8_t(id));
-    if (idx >= 0) {
-        mBitmap &= ~(1<<(31-id));
-        mLayers.removeItemsAt(idx);
+    int32_t name = layer->getToken();
+    if (name >= 0) {
+        int32_t mask = 1LU<<name;
+        if ((android_atomic_and(~mask, &mBitmap) & mask) == 0) {
+            LOGW("token %d wasn't marked as used %08x", name, int(mBitmap));
+        }
     }
 }
 
-bool Client::isValid(int32_t i) const {
-    return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
+sp<IMemoryHeap> UserClient::getControlBlock() const {
+    return mCblkHeap;
 }
 
-sp<LayerBaseClient> Client::getLayerUser(int32_t i) const {
-    sp<LayerBaseClient> lbc;
-    ssize_t idx = mInUse.indexOf(uint8_t(i));
-    if (idx >= 0) {
-        lbc = mLayers[idx].promote();
-        LOGE_IF(lbc==0, "getLayerUser(i=%d), idx=%d is dead", int(i), int(idx));
-    }
-    return lbc;
-}
-
-void Client::dump(const char* what)
+ssize_t UserClient::getTokenForSurface(const sp<ISurface>& sur) const
 {
+    int32_t name = NAME_NOT_FOUND;
+    sp<Layer> layer(mFlinger->getLayer(sur));
+    if (layer == 0) return name;
+
+    // if this layer already has a token, just return it
+    name = layer->getToken();
+    if ((name >= 0) && (layer->getClient() == this))
+        return name;
+
+    name = 0;
+    do {
+        int32_t mask = 1LU<<name;
+        if ((android_atomic_or(mask, &mBitmap) & mask) == 0) {
+            // we found and locked that name
+            status_t err = layer->setToken(
+                    const_cast<UserClient*>(this), ctrlblk, name);
+            if (err != NO_ERROR) {
+                // free the name
+                android_atomic_and(~mask, &mBitmap);
+                name = err;
+            }
+            break;
+        }
+        if (++name > 31)
+            name = NO_MEMORY;
+    } while(name >= 0);
+
+    //LOGD("getTokenForSurface(%p) => %d (client=%p, bitmap=%08lx)",
+    //        sur->asBinder().get(), name, this, mBitmap);
+    return name;
 }
 
-// ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
-
-BClient::BClient(SurfaceFlinger *flinger, ClientID cid, const sp<IMemoryHeap>& cblk)
-    : mId(cid), mFlinger(flinger), mCblk(cblk)
-{
-}
-
-BClient::~BClient() {
-    // destroy all resources attached to this client
-    mFlinger->destroyConnection(mId);
-}
-
-sp<IMemoryHeap> BClient::getControlBlock() const {
-    return mCblk;
-}
-
-sp<ISurface> BClient::createSurface(
-        ISurfaceFlingerClient::surface_data_t* params, int pid,
+sp<ISurface> UserClient::createSurface(
+        ISurfaceComposerClient::surface_data_t* params, int pid,
         const String8& name,
         DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
-        uint32_t flags)
-{
-    return mFlinger->createSurface(mId, pid, name, params, display, w, h,
-            format, flags);
+        uint32_t flags) {
+    return 0;
 }
-
-status_t BClient::destroySurface(SurfaceID sid)
-{
-    sid |= (mId << 16); // add the client-part to id
-    return mFlinger->removeSurface(sid);
+status_t UserClient::destroySurface(SurfaceID sid) {
+    return INVALID_OPERATION;
 }
-
-status_t BClient::setState(int32_t count, const layer_state_t* states)
-{
-    return mFlinger->setClientState(mId, count, states);
+status_t UserClient::setState(int32_t count, const layer_state_t* states) {
+    return INVALID_OPERATION;
 }
 
 // ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index d75dc15..8ecfc01 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -29,74 +29,96 @@
 
 #include <binder/IMemory.h>
 #include <binder/Permission.h>
+#include <binder/BinderService.h>
 
 #include <ui/PixelFormat.h>
 #include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 #include "Barrier.h"
 #include "Layer.h"
-#include "Tokenizer.h"
 
 #include "MessageQueue.h"
 
-struct copybit_device_t;
-struct overlay_device_t;
-
 namespace android {
 
 // ---------------------------------------------------------------------------
 
 class Client;
-class BClient;
 class DisplayHardware;
 class FreezeLock;
 class Layer;
+class LayerBlur;
+class LayerDim;
 class LayerBuffer;
 
-typedef int32_t ClientID;
-
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
 // ---------------------------------------------------------------------------
 
-class Client : public RefBase
+class Client : public BnSurfaceComposerClient
 {
 public:
-            Client(ClientID cid, const sp<SurfaceFlinger>& flinger);
-            ~Client();
+        Client(const sp<SurfaceFlinger>& flinger);
+        ~Client();
 
-            int32_t                 generateId(int pid);
-            void                    free(int32_t id);
-            status_t                bindLayer(const sp<LayerBaseClient>& layer, int32_t id);
+    status_t initCheck() const;
 
-    inline  bool                    isValid(int32_t i) const;
-    sp<LayerBaseClient>             getLayerUser(int32_t i) const;
-    void                            dump(const char* what);
-    
-    const Vector< wp<LayerBaseClient> >& getLayers() const { 
-        return mLayers; 
-    }
-    
-    const sp<IMemoryHeap>& getControlBlockMemory() const {
-        return mCblkHeap; 
-    }
-    
-    // pointer to this client's control block
-    SharedClient*           ctrlblk;
-    ClientID                cid;
+    // protected by SurfaceFlinger::mStateLock
+    ssize_t attachLayer(const sp<LayerBaseClient>& layer);
+    void detachLayer(const LayerBaseClient* layer);
+    sp<LayerBaseClient> getLayerUser(int32_t i) const;
 
-    
 private:
-    int getClientPid() const { return mPid; }
-        
-    int                             mPid;
-    uint32_t                        mBitmap;
-    SortedVector<uint8_t>           mInUse;
-    Vector< wp<LayerBaseClient> >   mLayers;
-    sp<IMemoryHeap>                 mCblkHeap;
-    sp<SurfaceFlinger>              mFlinger;
+
+    // ISurfaceComposerClient interface
+    virtual sp<IMemoryHeap> getControlBlock() const;
+    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const;
+    virtual sp<ISurface> createSurface(
+            surface_data_t* params, int pid, const String8& name,
+            DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
+            uint32_t flags);
+    virtual status_t destroySurface(SurfaceID surfaceId);
+    virtual status_t setState(int32_t count, const layer_state_t* states);
+
+    DefaultKeyedVector< size_t, wp<LayerBaseClient> > mLayers;
+    sp<SurfaceFlinger> mFlinger;
+    int32_t mNameGenerator;
+};
+
+class UserClient : public BnSurfaceComposerClient
+{
+public:
+    // pointer to this client's control block
+    SharedClient* ctrlblk;
+
+public:
+        UserClient(const sp<SurfaceFlinger>& flinger);
+        ~UserClient();
+
+    status_t initCheck() const;
+
+    // protected by SurfaceFlinger::mStateLock
+    void detachLayer(const Layer* layer);
+
+private:
+
+    // ISurfaceComposerClient interface
+    virtual sp<IMemoryHeap> getControlBlock() const;
+    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const;
+    virtual sp<ISurface> createSurface(
+            surface_data_t* params, int pid, const String8& name,
+            DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
+            uint32_t flags);
+    virtual status_t destroySurface(SurfaceID surfaceId);
+    virtual status_t setState(int32_t count, const layer_state_t* states);
+
+    // atomic-ops
+    mutable volatile int32_t mBitmap;
+
+    sp<IMemoryHeap> mCblkHeap;
+    sp<SurfaceFlinger> mFlinger;
 };
 
 // ---------------------------------------------------------------------------
@@ -143,11 +165,13 @@
     eTraversalNeeded        = 0x02
 };
 
-class SurfaceFlinger : public BnSurfaceComposer, protected Thread
+class SurfaceFlinger :
+        public BinderService<SurfaceFlinger>,
+        public BnSurfaceComposer,
+        protected Thread
 {
 public:
-    static void instantiate();
-    static void shutdown();
+    static char const* getServiceName() { return "SurfaceFlinger"; }
 
                     SurfaceFlinger();
     virtual         ~SurfaceFlinger();
@@ -159,7 +183,8 @@
     virtual status_t dump(int fd, const Vector<String16>& args);
 
     // ISurfaceComposer interface
-    virtual sp<ISurfaceFlingerClient>   createConnection();
+    virtual sp<ISurfaceComposerClient>  createConnection();
+    virtual sp<ISurfaceComposerClient>  createClientConnection();
     virtual sp<IMemoryHeap>             getCblk() const;
     virtual void                        bootFinished();
     virtual void                        openGlobalTransaction();
@@ -174,13 +199,14 @@
 
             overlay_control_device_t* getOverlayEngine() const;
 
-            
     status_t removeLayer(const sp<LayerBase>& layer);
     status_t addLayer(const sp<LayerBase>& layer);
     status_t invalidateLayerVisibility(const sp<LayerBase>& layer);
-    
+
+    sp<Layer> getLayer(const sp<ISurface>& sur) const;
+
 private:
-    friend class BClient;
+    friend class Client;
     friend class LayerBase;
     friend class LayerBuffer;
     friend class LayerBaseClient;
@@ -189,47 +215,47 @@
     friend class LayerBlur;
     friend class LayerDim;
 
-    sp<ISurface> createSurface(ClientID client, int pid, const String8& name,
-            ISurfaceFlingerClient::surface_data_t* params,
+    sp<ISurface> createSurface(const sp<Client>& client,
+            int pid, const String8& name,
+            ISurfaceComposerClient::surface_data_t* params,
             DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
             uint32_t flags);
 
-    sp<LayerBaseClient> createNormalSurfaceLocked(
+    sp<Layer> createNormalSurface(
             const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags,
+            uint32_t w, uint32_t h, uint32_t flags,
             PixelFormat& format);
 
-    sp<LayerBaseClient> createBlurSurfaceLocked(
+    sp<LayerBlur> createBlurSurface(
             const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+            uint32_t w, uint32_t h, uint32_t flags);
 
-    sp<LayerBaseClient> createDimSurfaceLocked(
+    sp<LayerDim> createDimSurface(
             const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+            uint32_t w, uint32_t h, uint32_t flags);
 
-    sp<LayerBaseClient> createPushBuffersSurfaceLocked(
+    sp<LayerBuffer> createPushBuffersSurface(
             const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
+            uint32_t w, uint32_t h, uint32_t flags);
 
-    status_t removeSurface(SurfaceID surface_id);
+    status_t removeSurface(const sp<Client>& client, SurfaceID sid);
     status_t destroySurface(const sp<LayerBaseClient>& layer);
-    status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states);
+    status_t setClientState(const sp<Client>& client,
+            int32_t count, const layer_state_t* states);
 
-
-    class LayerVector {
+    class LayerVector : public SortedVector< sp<LayerBase> > {
     public:
-        inline              LayerVector() { }
-                            LayerVector(const LayerVector&);
-        inline size_t       size() const { return layers.size(); }
-        inline sp<LayerBase> const* array() const { return layers.array(); }
-        ssize_t             add(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t);
-        ssize_t             remove(const sp<LayerBase>&);
-        ssize_t             reorder(const sp<LayerBase>&, Vector< sp<LayerBase> >::compar_t);
-        ssize_t             indexOf(const sp<LayerBase>& key, size_t guess=0) const;
-        inline sp<LayerBase> operator [] (size_t i) const { return layers[i]; }
-    private:
-        KeyedVector< sp<LayerBase> , size_t> lookup;
-        Vector< sp<LayerBase> >              layers;
+        LayerVector() { }
+        LayerVector(const LayerVector& rhs) : SortedVector< sp<LayerBase> >(rhs) { }
+        virtual int do_compare(const void* lhs, const void* rhs) const {
+            const sp<LayerBase>& l(*reinterpret_cast<const sp<LayerBase>*>(lhs));
+            const sp<LayerBase>& r(*reinterpret_cast<const sp<LayerBase>*>(rhs));
+            // sort layers by Z order
+            uint32_t lz = l->currentState().z;
+            uint32_t rz = r->currentState().z;
+            // then by sequence, so we get a stable ordering
+            return (lz != rz) ? (lz - rz) : (l->sequence - r->sequence);
+        }
     };
 
     struct State {
@@ -256,8 +282,6 @@
 public:     // hack to work around gcc 4.0.3 bug
             void        signalEvent();
 private:
-            void        signalDelayedEvent(nsecs_t delay);
-
             void        handleConsoleEvents();
             void        handleTransaction(uint32_t transactionFlags);
             void        handleTransactionLocked(
@@ -278,15 +302,14 @@
             void        unlockClients();
 
 
-            void        destroyConnection(ClientID cid);
-            sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const;
+            ssize_t     addClientLayer(const sp<Client>& client,
+                    const sp<LayerBaseClient>& lbc);
             status_t    addLayer_l(const sp<LayerBase>& layer);
             status_t    removeLayer_l(const sp<LayerBase>& layer);
             status_t    purgatorizeLayer_l(const sp<LayerBase>& layer);
-            void        free_resources_l();
 
             uint32_t    getTransactionFlags(uint32_t flags);
-            uint32_t    setTransactionFlags(uint32_t flags, nsecs_t delay = 0);
+            uint32_t    setTransactionFlags(uint32_t flags);
             void        commitTransaction();
 
 
@@ -310,9 +333,13 @@
            
 
     mutable     MessageQueue    mEventQueue;
-    
-                
-                
+
+    status_t postMessageAsync(const sp<MessageBase>& msg,
+            nsecs_t reltime=0, uint32_t flags = 0);
+
+    status_t postMessageSync(const sp<MessageBase>& msg,
+            nsecs_t reltime=0, uint32_t flags = 0);
+
                 // access must be protected by mStateLock
     mutable     Mutex                   mStateLock;
                 State                   mCurrentState;
@@ -321,14 +348,11 @@
     volatile    int32_t                 mTransactionCount;
                 Condition               mTransactionCV;
                 bool                    mResizeTransationPending;
-                
+
                 // protected by mStateLock (but we could use another lock)
-                Tokenizer                               mTokens;
-                DefaultKeyedVector<ClientID, sp<Client> >   mClientsMap;
-                DefaultKeyedVector<SurfaceID, sp<LayerBaseClient> >   mLayerMap;
-                GraphicPlane                            mGraphicPlanes[1];
-                bool                                    mLayersRemoved;
-                Vector< sp<Client> >                    mDisconnectedClients;
+                GraphicPlane                mGraphicPlanes[1];
+                bool                        mLayersRemoved;
+                DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap;
 
                 // constant members (no synchronization needed for access)
                 sp<IMemoryHeap>             mServerHeap;
@@ -350,6 +374,8 @@
                 bool                        mFreezeDisplay;
                 int32_t                     mFreezeCount;
                 nsecs_t                     mFreezeDisplayTime;
+                Vector< sp<LayerBase> >     mVisibleLayersSortedByZ;
+
 
                 // don't use a lock for these, we don't care
                 int                         mDebugRegion;
@@ -389,32 +415,6 @@
 };
 
 // ---------------------------------------------------------------------------
-
-class BClient : public BnSurfaceFlingerClient
-{
-public:
-    BClient(SurfaceFlinger *flinger, ClientID cid,
-            const sp<IMemoryHeap>& cblk);
-    ~BClient();
-
-    // ISurfaceFlingerClient interface
-    virtual sp<IMemoryHeap> getControlBlock() const;
-
-    virtual sp<ISurface> createSurface(
-            surface_data_t* params, int pid, const String8& name,
-            DisplayID display, uint32_t w, uint32_t h,PixelFormat format,
-            uint32_t flags);
-
-    virtual status_t destroySurface(SurfaceID surfaceId);
-    virtual status_t setState(int32_t count, const layer_state_t* states);
-
-private:
-    ClientID            mId;
-    SurfaceFlinger*     mFlinger;
-    sp<IMemoryHeap>     mCblk;
-};
-
-// ---------------------------------------------------------------------------
 }; // namespace android
 
 #endif // ANDROID_SURFACE_FLINGER_H
diff --git a/services/surfaceflinger/TextureManager.cpp b/services/surfaceflinger/TextureManager.cpp
new file mode 100644
index 0000000..76f6159
--- /dev/null
+++ b/services/surfaceflinger/TextureManager.cpp
@@ -0,0 +1,341 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <hardware/hardware.h>
+
+#include "clz.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "GLExtensions.h"
+#include "TextureManager.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+TextureManager::TextureManager()
+    : mGLExtensions(GLExtensions::getInstance())
+{
+}
+
+GLenum TextureManager::getTextureTarget(const Image* image) {
+#if defined(GL_OES_texture_external)
+    switch (image->target) {
+        case Texture::TEXTURE_EXTERNAL:
+            return GL_TEXTURE_EXTERNAL_OES;
+    }
+#endif
+    return GL_TEXTURE_2D;
+}
+
+status_t TextureManager::initTexture(Texture* texture)
+{
+    if (texture->name != -1UL)
+        return INVALID_OPERATION;
+
+    GLuint textureName = -1;
+    glGenTextures(1, &textureName);
+    texture->name = textureName;
+    texture->width = 0;
+    texture->height = 0;
+
+    const GLenum target = GL_TEXTURE_2D;
+    glBindTexture(target, textureName);
+    glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    return NO_ERROR;
+}
+
+status_t TextureManager::initTexture(Image* pImage, int32_t format)
+{
+    if (pImage->name != -1UL)
+        return INVALID_OPERATION;
+
+    GLuint textureName = -1;
+    glGenTextures(1, &textureName);
+    pImage->name = textureName;
+    pImage->width = 0;
+    pImage->height = 0;
+
+    GLenum target = GL_TEXTURE_2D;
+#if defined(GL_OES_texture_external)
+    if (GLExtensions::getInstance().haveTextureExternal()) {
+        if (format && isYuvFormat(format)) {
+            target = GL_TEXTURE_EXTERNAL_OES;
+            pImage->target = Texture::TEXTURE_EXTERNAL;
+        }
+    }
+#endif
+
+    glBindTexture(target, textureName);
+    glTexParameterx(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+    glTexParameterx(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+    glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+    return NO_ERROR;
+}
+
+bool TextureManager::isSupportedYuvFormat(int format)
+{
+    switch (format) {
+    case HAL_PIXEL_FORMAT_YV12:
+        return true;
+    }
+    return false;
+}
+
+bool TextureManager::isYuvFormat(int format)
+{
+    switch (format) {
+    // supported YUV formats
+    case HAL_PIXEL_FORMAT_YV12:
+    // Legacy/deprecated YUV formats
+    case HAL_PIXEL_FORMAT_YCbCr_422_SP:
+    case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+    case HAL_PIXEL_FORMAT_YCbCr_422_I:
+        return true;
+    }
+
+    // Any OEM format needs to be considered
+    if (format>=0x100 && format<=0x1FF)
+        return true;
+
+    return false;
+}
+
+status_t TextureManager::initEglImage(Image* pImage,
+        EGLDisplay dpy, const sp<GraphicBuffer>& buffer)
+{
+    status_t err = NO_ERROR;
+    if (!pImage->dirty) return err;
+
+    // free the previous image
+    if (pImage->image != EGL_NO_IMAGE_KHR) {
+        eglDestroyImageKHR(dpy, pImage->image);
+        pImage->image = EGL_NO_IMAGE_KHR;
+    }
+
+    // construct an EGL_NATIVE_BUFFER_ANDROID
+    android_native_buffer_t* clientBuf = buffer->getNativeBuffer();
+
+    // create the new EGLImageKHR
+    const EGLint attrs[] = {
+            EGL_IMAGE_PRESERVED_KHR,    EGL_TRUE,
+            EGL_NONE,                   EGL_NONE
+    };
+    pImage->image = eglCreateImageKHR(
+            dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID,
+            (EGLClientBuffer)clientBuf, attrs);
+
+    if (pImage->image != EGL_NO_IMAGE_KHR) {
+        if (pImage->name == -1UL) {
+            initTexture(pImage, buffer->format);
+        }
+        const GLenum target = getTextureTarget(pImage);
+        glBindTexture(target, pImage->name);
+        glEGLImageTargetTexture2DOES(target, (GLeglImageOES)pImage->image);
+        GLint error = glGetError();
+        if (error != GL_NO_ERROR) {
+            LOGE("glEGLImageTargetTexture2DOES(%p) failed err=0x%04x",
+                    pImage->image, error);
+            err = INVALID_OPERATION;
+        } else {
+            // Everything went okay!
+            pImage->dirty  = false;
+            pImage->width  = clientBuf->width;
+            pImage->height = clientBuf->height;
+        }
+    } else {
+        LOGE("eglCreateImageKHR() failed. err=0x%4x", eglGetError());
+        err = INVALID_OPERATION;
+    }
+    return err;
+}
+
+status_t TextureManager::loadTexture(Texture* texture,
+        const Region& dirty, const GGLSurface& t)
+{
+    if (texture->name == -1UL) {
+        status_t err = initTexture(texture);
+        LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err));
+        return err;
+    }
+
+    if (texture->target != Texture::TEXTURE_2D)
+        return INVALID_OPERATION;
+
+    glBindTexture(GL_TEXTURE_2D, texture->name);
+
+    /*
+     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
+     * GL_UNPACK_ALIGNMENT is a limited form of stride).
+     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
+     * need to do something reasonable (here creating a bigger texture).
+     *
+     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
+     *
+     * This situation doesn't happen often, but some h/w have a limitation
+     * for their framebuffer (eg: must be multiple of 8 pixels), and
+     * we need to take that into account when using these buffers as
+     * textures.
+     *
+     * This should never be a problem with POT textures
+     */
+
+    int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
+    unpack = 1 << ((unpack > 3) ? 3 : unpack);
+    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
+
+    /*
+     * round to POT if needed
+     */
+    if (!mGLExtensions.haveNpot()) {
+        texture->NPOTAdjust = true;
+    }
+
+    if (texture->NPOTAdjust) {
+        // find the smallest power-of-two that will accommodate our surface
+        texture->potWidth  = 1 << (31 - clz(t.width));
+        texture->potHeight = 1 << (31 - clz(t.height));
+        if (texture->potWidth  < t.width)  texture->potWidth  <<= 1;
+        if (texture->potHeight < t.height) texture->potHeight <<= 1;
+        texture->wScale = float(t.width)  / texture->potWidth;
+        texture->hScale = float(t.height) / texture->potHeight;
+    } else {
+        texture->potWidth  = t.width;
+        texture->potHeight = t.height;
+    }
+
+    Rect bounds(dirty.bounds());
+    GLvoid* data = 0;
+    if (texture->width != t.width || texture->height != t.height) {
+        texture->width  = t.width;
+        texture->height = t.height;
+
+        // texture size changed, we need to create a new one
+        bounds.set(Rect(t.width, t.height));
+        if (t.width  == texture->potWidth &&
+            t.height == texture->potHeight) {
+            // we can do it one pass
+            data = t.data;
+        }
+
+        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGB, texture->potWidth, texture->potHeight, 0,
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
+        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
+        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
+                    GL_RGBA, GL_UNSIGNED_BYTE, data);
+        } else if (isSupportedYuvFormat(t.format)) {
+            // just show the Y plane of YUV buffers
+            glTexImage2D(GL_TEXTURE_2D, 0,
+                    GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
+        } else {
+            // oops, we don't handle this format!
+            LOGE("texture=%d, using format %d, which is not "
+                 "supported by the GL", texture->name, t.format);
+        }
+    }
+    if (!data) {
+        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+                    t.data + bounds.top*t.stride*2);
+        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
+                    t.data + bounds.top*t.stride*2);
+        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
+                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_RGBA, GL_UNSIGNED_BYTE,
+                    t.data + bounds.top*t.stride*4);
+        } else if (isSupportedYuvFormat(t.format)) {
+            // just show the Y plane of YUV buffers
+            glTexSubImage2D(GL_TEXTURE_2D, 0,
+                    0, bounds.top, t.width, bounds.height(),
+                    GL_LUMINANCE, GL_UNSIGNED_BYTE,
+                    t.data + bounds.top*t.stride);
+        }
+    }
+    return NO_ERROR;
+}
+
+void TextureManager::activateTexture(const Texture& texture, bool filter)
+{
+    const GLenum target = getTextureTarget(&texture);
+    if (target == GL_TEXTURE_2D) {
+        glBindTexture(GL_TEXTURE_2D, texture.name);
+        glEnable(GL_TEXTURE_2D);
+#if defined(GL_OES_texture_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
+        }
+    } else {
+        glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture.name);
+        glEnable(GL_TEXTURE_EXTERNAL_OES);
+        glDisable(GL_TEXTURE_2D);
+#endif
+    }
+
+    if (filter) {
+        glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    } else {
+        glTexParameterx(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    }
+}
+
+void TextureManager::deactivateTextures()
+{
+    glDisable(GL_TEXTURE_2D);
+#if defined(GL_OES_texture_external)
+    if (GLExtensions::getInstance().haveTextureExternal()) {
+        glDisable(GL_TEXTURE_EXTERNAL_OES);
+    }
+#endif
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/TextureManager.h b/services/surfaceflinger/TextureManager.h
new file mode 100644
index 0000000..18c4348
--- /dev/null
+++ b/services/surfaceflinger/TextureManager.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#ifndef ANDROID_TEXTURE_MANAGER_H
+#define ANDROID_TEXTURE_MANAGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+
+#include <ui/Region.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class GLExtensions;
+class GraphicBuffer;
+
+// ---------------------------------------------------------------------------
+
+struct Image {
+    enum { TEXTURE_2D=0, TEXTURE_EXTERNAL=1 };
+    Image() : name(-1U), image(EGL_NO_IMAGE_KHR), width(0), height(0),
+        dirty(1), target(TEXTURE_2D) { }
+    GLuint        name;
+    EGLImageKHR   image;
+    GLuint        width;
+    GLuint        height;
+    unsigned      dirty     : 1;
+    unsigned      target    : 1;
+};
+
+struct Texture : public Image {
+    Texture() : Image(), NPOTAdjust(0) { }
+    GLuint      potWidth;
+    GLuint      potHeight;
+    GLfloat     wScale;
+    GLfloat     hScale;
+    unsigned    NPOTAdjust  : 1;
+};
+
+// ---------------------------------------------------------------------------
+
+class TextureManager {
+    const GLExtensions& mGLExtensions;
+    static status_t initTexture(Image* texture, int32_t format);
+    static status_t initTexture(Texture* texture);
+    static bool isSupportedYuvFormat(int format);
+    static bool isYuvFormat(int format);
+    static GLenum getTextureTarget(const Image* pImage);
+public:
+
+    TextureManager();
+
+    // load bitmap data into the active buffer
+    status_t loadTexture(Texture* texture,
+            const Region& dirty, const GGLSurface& t);
+
+    // make active buffer an EGLImage if needed
+    status_t initEglImage(Image* texture,
+            EGLDisplay dpy, const sp<GraphicBuffer>& buffer);
+
+    // activate a texture
+    static void activateTexture(const Texture& texture, bool filter);
+
+    // deactivate a texture
+    static void deactivateTextures();
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_TEXTURE_MANAGER_H
diff --git a/services/surfaceflinger/Tokenizer.cpp b/services/surfaceflinger/Tokenizer.cpp
deleted file mode 100644
index be3a239..0000000
--- a/services/surfaceflinger/Tokenizer.cpp
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#include <stdio.h>
-
-#include "Tokenizer.h"
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-ANDROID_BASIC_TYPES_TRAITS(Tokenizer::run_t)
-
-Tokenizer::Tokenizer()
-{
-}
-
-Tokenizer::Tokenizer(const Tokenizer& other)
-    : mRanges(other.mRanges)
-{
-}
-
-Tokenizer::~Tokenizer()
-{
-}
-
-uint32_t Tokenizer::acquire()
-{
-    if (!mRanges.size() || mRanges[0].first) {
-        _insertTokenAt(0,0);
-        return 0;
-    }
-    
-    // just extend the first run
-    const run_t& run = mRanges[0];
-    uint32_t token = run.first + run.length;
-    _insertTokenAt(token, 1);
-    return token;
-}
-
-bool Tokenizer::isAcquired(uint32_t token) const
-{
-    return (_indexOrderOf(token) >= 0);
-}
-
-status_t Tokenizer::reserve(uint32_t token)
-{
-    size_t o;
-    const ssize_t i = _indexOrderOf(token, &o);
-    if (i >= 0) {
-        return BAD_VALUE; // this token is already taken
-    }
-    ssize_t err = _insertTokenAt(token, o);
-    return (err<0) ? err : status_t(NO_ERROR);
-}
-
-status_t Tokenizer::release(uint32_t token)
-{
-    const ssize_t i = _indexOrderOf(token);
-    if (i >= 0) {
-        const run_t& run = mRanges[i];
-        if ((token >= run.first) && (token < run.first+run.length)) {
-            // token in this range, we need to split
-            run_t& run = mRanges.editItemAt(i);
-            if ((token == run.first) || (token == run.first+run.length-1)) {
-                if (token == run.first) {
-                    run.first += 1;
-                }
-                run.length -= 1;
-                if (run.length == 0) {
-                    // XXX: should we systematically remove a run that's empty?
-                    mRanges.removeItemsAt(i);
-                }
-            } else {
-                // split the run
-                run_t new_run;
-                new_run.first = token+1;
-                new_run.length = run.first+run.length - new_run.first;
-                run.length = token - run.first;
-                mRanges.insertAt(new_run, i+1);
-            }
-            return NO_ERROR;
-        }
-    }
-    return NAME_NOT_FOUND;
-}
-
-ssize_t Tokenizer::_indexOrderOf(uint32_t token, size_t* order) const
-{
-    // binary search
-    ssize_t err = NAME_NOT_FOUND;
-    ssize_t l = 0;
-    ssize_t h = mRanges.size()-1;
-    ssize_t mid;
-    const run_t* a = mRanges.array();
-    while (l <= h) {
-        mid = l + (h - l)/2;
-        const run_t* const curr = a + mid;
-        int c = 0;
-        if (token < curr->first)                        c = 1;
-        else if (token >= curr->first+curr->length)     c = -1;
-        if (c == 0) {
-            err = l = mid;
-            break;
-        } else if (c < 0) {
-            l = mid + 1;
-        } else {
-            h = mid - 1;
-        }
-    }
-    if (order) *order = l;
-    return err;
-}
-
-ssize_t Tokenizer::_insertTokenAt(uint32_t token, size_t index)
-{
-    const size_t c = mRanges.size();
-
-    if (index >= 1) {
-        // do we need to merge with the previous run?
-        run_t& p = mRanges.editItemAt(index-1);
-        if (p.first+p.length == token) {
-            p.length += 1;
-            if (index < c) {
-                const run_t& n = mRanges[index];
-                if (token+1 == n.first) {
-                    p.length += n.length;
-                    mRanges.removeItemsAt(index);
-                }
-            }
-            return index;
-        }
-    }
-    
-    if (index < c) {
-        // do we need to merge with the next run?
-        run_t& n = mRanges.editItemAt(index);
-        if (token+1 == n.first) {
-            n.first -= 1;
-            n.length += 1;
-            return index;
-        }
-    }
-
-    return mRanges.insertAt(run_t(token,1), index);
-}
-
-void Tokenizer::dump() const
-{
-    const run_t* ranges = mRanges.array();
-    const size_t c = mRanges.size();
-    printf("Tokenizer (%p, size = %d)\n", this, int(c));
-    for (size_t i=0 ; i<c ; i++) {
-        printf("%u: (%u, %u)\n", i,
-                uint32_t(ranges[i].first), uint32_t(ranges[i].length));
-    }
-}
-
-}; // namespace android
-
diff --git a/services/surfaceflinger/Tokenizer.h b/services/surfaceflinger/Tokenizer.h
deleted file mode 100644
index 6b3057d..0000000
--- a/services/surfaceflinger/Tokenizer.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#ifndef ANDROID_TOKENIZER_H
-#define ANDROID_TOKENIZER_H
-
-#include <utils/Vector.h>
-#include <utils/Errors.h>
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-class Tokenizer
-{
-public:
-                Tokenizer();
-                Tokenizer(const Tokenizer& other);
-                ~Tokenizer();
-
-    uint32_t    acquire();
-    status_t    reserve(uint32_t token);
-    status_t    release(uint32_t token);
-    bool        isAcquired(uint32_t token) const;
-
-    void dump() const;
-
-    struct run_t {
-        run_t() {};
-        run_t(uint32_t f, uint32_t l) : first(f), length(l) {}
-        uint32_t    first;
-        uint32_t    length;
-    };
-private:
-    ssize_t _indexOrderOf(uint32_t token, size_t* order=0) const;
-    ssize_t _insertTokenAt(uint32_t token, size_t index);
-    Vector<run_t>   mRanges;
-};
-
-}; // namespace android
-
-// ----------------------------------------------------------------------------
-
-#endif // ANDROID_TOKENIZER_H
diff --git a/services/surfaceflinger/Transform.cpp b/services/surfaceflinger/Transform.cpp
index 175f989..5e27cc9 100644
--- a/services/surfaceflinger/Transform.cpp
+++ b/services/surfaceflinger/Transform.cpp
@@ -229,14 +229,13 @@
     return r;
 }
 
-void Transform::transform(fixed1616* point, int x, int y) const
+void Transform::transform(float* point, int x, int y) const
 {
-    const float toFixed = 65536.0f;
     const mat33& M(mMatrix);
     vec2 v(x, y);
     v = transform(v);
-    point[0] = v[0] * toFixed;
-    point[1] = v[1] * toFixed;
+    point[0] = v[0];
+    point[1] = v[1];
 }
 
 Rect Transform::makeBounds(int w, int h) const
diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
index 2e5b893..20fa11a 100644
--- a/services/surfaceflinger/Transform.h
+++ b/services/surfaceflinger/Transform.h
@@ -37,8 +37,6 @@
            explicit Transform(uint32_t orientation);
                     ~Transform();
 
-            typedef int32_t fixed1616;
-
             // FIXME: must match OVERLAY_TRANSFORM_*, pull from hardware.h
             enum orientation_flags {
                 ROT_0   = 0x00000000,
@@ -76,7 +74,7 @@
 
             // transform data
             Rect    makeBounds(int w, int h) const;
-            void    transform(fixed1616* point, int x, int y) const;
+            void    transform(float* point, int x, int y) const;
             Region  transform(const Region& reg) const;
             Transform operator * (const Transform& rhs) const;
 
diff --git a/services/surfaceflinger/tests/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk
new file mode 100644
index 0000000..ce0e807
--- /dev/null
+++ b/services/surfaceflinger/tests/surface/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	surface.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+    libui \
+    libsurfaceflinger_client
+
+LOCAL_MODULE:= test-surface
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
new file mode 100644
index 0000000..b4de4b4
--- /dev/null
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -0,0 +1,54 @@
+#include <cutils/memory.h>
+
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <ui/Overlay.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+    // set up the thread-pool
+    sp<ProcessState> proc(ProcessState::self());
+    ProcessState::self()->startThreadPool();
+
+    // create a client to surfaceflinger
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
+    
+    // create pushbuffer surface
+    sp<SurfaceControl> surfaceControl = client->createSurface(
+            getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565);
+    client->openTransaction();
+    surfaceControl->setLayer(100000);
+    client->closeTransaction();
+
+    // pretend it went cross-process
+    Parcel parcel;
+    SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel);
+    parcel.setDataPosition(0);
+    sp<Surface> surface = Surface::readFromParcel(parcel);
+    ANativeWindow* window = surface.get();
+
+    printf("window=%p\n", window);
+
+    int err = native_window_set_buffer_count(window, 8);
+    android_native_buffer_t* buffer;
+
+    for (int i=0 ; i<8 ; i++) {
+        window->dequeueBuffer(window, &buffer);
+        printf("buffer %d: %p\n", i, buffer);
+    }
+
+    printf("test complete. CTRL+C to finish.\n");
+
+    IPCThreadState::self()->joinThreadPool();
+    return 0;
+}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce522c8..ce40b5d 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -85,7 +85,8 @@
 
     // TODO(oam): Test VPN when EFS is enabled (will do later)...
     public static String getProfilePath() {
-        return Environment.getDataDirectory().getPath() + PROFILES_PATH;
+        // This call will return the correct path if Encrypted FS is enabled or not.
+        return Environment.getSecureDataDirectory().getPath() + PROFILES_PATH;
     }
 
     /**
