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/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
deleted file mode 100644
index df5c166..0000000
--- a/camera/libcameraservice/Android.mk
+++ /dev/null
@@ -1,71 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#
-# Set USE_CAMERA_STUB for non-emulator and non-simulator builds, if you want
-# the camera service to use the fake camera.  For emulator or simulator builds,
-# we always use the fake camera.
-
-ifeq ($(USE_CAMERA_STUB),)
-USE_CAMERA_STUB:=false
-ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
-USE_CAMERA_STUB:=true
-endif #libcamerastub
-endif
-
-ifeq ($(USE_CAMERA_STUB),true)
-#
-# libcamerastub
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=               \
-    CameraHardwareStub.cpp      \
-    FakeCamera.cpp
-
-LOCAL_MODULE:= libcamerastub
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-LOCAL_SHARED_LIBRARIES:= libui
-
-include $(BUILD_STATIC_LIBRARY)
-endif # USE_CAMERA_STUB
-
-#
-# libcameraservice
-#
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=               \
-    CameraService.cpp
-
-LOCAL_SHARED_LIBRARIES:= \
-    libui \
-    libutils \
-    libbinder \
-    libcutils \
-    libmedia \
-    libcamera_client \
-    libsurfaceflinger_client
-
-LOCAL_MODULE:= libcameraservice
-
-LOCAL_CFLAGS += -DLOG_TAG=\"CameraService\"
-
-ifeq ($(TARGET_SIMULATOR),true)
-LOCAL_CFLAGS += -DSINGLE_PROCESS
-endif
-
-ifeq ($(USE_CAMERA_STUB), true)
-LOCAL_STATIC_LIBRARIES += libcamerastub
-LOCAL_CFLAGS += -include CameraHardwareStub.h
-else
-LOCAL_SHARED_LIBRARIES += libcamera 
-endif
-
-include $(BUILD_SHARED_LIBRARY)
-
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp
deleted file mode 100644
index 8b66389..0000000
--- a/camera/libcameraservice/CameraHardwareStub.cpp
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "CameraHardwareStub"
-#include <utils/Log.h>
-
-#include "CameraHardwareStub.h"
-#include <utils/threads.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#include "CannedJpeg.h"
-
-namespace android {
-
-CameraHardwareStub::CameraHardwareStub()
-                  : mParameters(),
-                    mPreviewHeap(0),
-                    mRawHeap(0),
-                    mFakeCamera(0),
-                    mPreviewFrameSize(0),
-                    mNotifyCb(0),
-                    mDataCb(0),
-                    mDataCbTimestamp(0),
-                    mCallbackCookie(0),
-                    mMsgEnabled(0),
-                    mCurrentPreviewFrame(0)
-{
-    initDefaultParameters();
-}
-
-void CameraHardwareStub::initDefaultParameters()
-{
-    CameraParameters p;
-
-    p.set("preview-size-values","320x240");
-    p.setPreviewSize(320, 240);
-    p.setPreviewFrameRate(15);
-    p.setPreviewFormat("yuv422sp");
-
-    p.set("picture-size-values", "320x240");
-    p.setPictureSize(320, 240);
-    p.setPictureFormat("jpeg");
-
-    if (setParameters(p) != NO_ERROR) {
-        LOGE("Failed to set default parameters?!");
-    }
-}
-
-void CameraHardwareStub::initHeapLocked()
-{
-    // Create raw heap.
-    int picture_width, picture_height;
-    mParameters.getPictureSize(&picture_width, &picture_height);
-    mRawHeap = new MemoryHeapBase(picture_width * 2 * picture_height);
-
-    int preview_width, preview_height;
-    mParameters.getPreviewSize(&preview_width, &preview_height);
-    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);
-
-    // Note that we enforce yuv422 in setParameters().
-    int how_big = preview_width * preview_height * 2;
-
-    // If we are being reinitialized to the same size as before, no
-    // work needs to be done.
-    if (how_big == mPreviewFrameSize)
-        return;
-
-    mPreviewFrameSize = how_big;
-
-    // Make a new mmap'ed heap that can be shared across processes.
-    // use code below to test with pmem
-    mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
-    // Make an IMemory for each frame so that we can reuse them in callbacks.
-    for (int i = 0; i < kBufferCount; i++) {
-        mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);
-    }
-
-    // Recreate the fake camera to reflect the current size.
-    delete mFakeCamera;
-    mFakeCamera = new FakeCamera(preview_width, preview_height);
-}
-
-CameraHardwareStub::~CameraHardwareStub()
-{
-    delete mFakeCamera;
-    mFakeCamera = 0; // paranoia
-    singleton.clear();
-}
-
-sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const
-{
-    return mPreviewHeap;
-}
-
-sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const
-{
-    return mRawHeap;
-}
-
-void CameraHardwareStub::setCallbacks(notify_callback notify_cb,
-                                      data_callback data_cb,
-                                      data_callback_timestamp data_cb_timestamp,
-                                      void* user)
-{
-    Mutex::Autolock lock(mLock);
-    mNotifyCb = notify_cb;
-    mDataCb = data_cb;
-    mDataCbTimestamp = data_cb_timestamp;
-    mCallbackCookie = user;
-}
-
-void CameraHardwareStub::enableMsgType(int32_t msgType)
-{
-    Mutex::Autolock lock(mLock);
-    mMsgEnabled |= msgType;
-}
-
-void CameraHardwareStub::disableMsgType(int32_t msgType)
-{
-    Mutex::Autolock lock(mLock);
-    mMsgEnabled &= ~msgType;
-}
-
-bool CameraHardwareStub::msgTypeEnabled(int32_t msgType)
-{
-    Mutex::Autolock lock(mLock);
-    return (mMsgEnabled & msgType);
-}
-
-// ---------------------------------------------------------------------------
-
-int CameraHardwareStub::previewThread()
-{
-    mLock.lock();
-        // the attributes below can change under our feet...
-
-        int previewFrameRate = mParameters.getPreviewFrameRate();
-
-        // Find the offset within the heap of the current buffer.
-        ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize;
-
-        sp<MemoryHeapBase> heap = mPreviewHeap;
-
-        // this assumes the internal state of fake camera doesn't change
-        // (or is thread safe)
-        FakeCamera* fakeCamera = mFakeCamera;
-
-        sp<MemoryBase> buffer = mBuffers[mCurrentPreviewFrame];
-
-    mLock.unlock();
-
-    // TODO: here check all the conditions that could go wrong
-    if (buffer != 0) {
-        // Calculate how long to wait between frames.
-        int delay = (int)(1000000.0f / float(previewFrameRate));
-
-        // This is always valid, even if the client died -- the memory
-        // is still mapped in our process.
-        void *base = heap->base();
-
-        // Fill the current frame with the fake camera.
-        uint8_t *frame = ((uint8_t *)base) + offset;
-        fakeCamera->getNextFrameAsYuv422(frame);
-
-        //LOGV("previewThread: generated frame to buffer %d", mCurrentPreviewFrame);
-
-        // Notify the client of a new frame.
-        if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
-            mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie);
-
-        // Advance the buffer pointer.
-        mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
-
-        // Wait for it...
-        usleep(delay);
-    }
-
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::startPreview()
-{
-    Mutex::Autolock lock(mLock);
-    if (mPreviewThread != 0) {
-        // already running
-        return INVALID_OPERATION;
-    }
-    mPreviewThread = new PreviewThread(this);
-    return NO_ERROR;
-}
-
-void CameraHardwareStub::stopPreview()
-{
-    sp<PreviewThread> previewThread;
-
-    { // scope for the lock
-        Mutex::Autolock lock(mLock);
-        previewThread = mPreviewThread;
-    }
-
-    // don't hold the lock while waiting for the thread to quit
-    if (previewThread != 0) {
-        previewThread->requestExitAndWait();
-    }
-
-    Mutex::Autolock lock(mLock);
-    mPreviewThread.clear();
-}
-
-bool CameraHardwareStub::previewEnabled() {
-    return mPreviewThread != 0;
-}
-
-status_t CameraHardwareStub::startRecording()
-{
-    return UNKNOWN_ERROR;
-}
-
-void CameraHardwareStub::stopRecording()
-{
-}
-
-bool CameraHardwareStub::recordingEnabled()
-{
-    return false;
-}
-
-void CameraHardwareStub::releaseRecordingFrame(const sp<IMemory>& mem)
-{
-}
-
-// ---------------------------------------------------------------------------
-
-int CameraHardwareStub::beginAutoFocusThread(void *cookie)
-{
-    CameraHardwareStub *c = (CameraHardwareStub *)cookie;
-    return c->autoFocusThread();
-}
-
-int CameraHardwareStub::autoFocusThread()
-{
-    if (mMsgEnabled & CAMERA_MSG_FOCUS)
-        mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie);
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::autoFocus()
-{
-    Mutex::Autolock lock(mLock);
-    if (createThread(beginAutoFocusThread, this) == false)
-        return UNKNOWN_ERROR;
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::cancelAutoFocus()
-{
-    return NO_ERROR;
-}
-
-/*static*/ int CameraHardwareStub::beginPictureThread(void *cookie)
-{
-    CameraHardwareStub *c = (CameraHardwareStub *)cookie;
-    return c->pictureThread();
-}
-
-int CameraHardwareStub::pictureThread()
-{
-    if (mMsgEnabled & CAMERA_MSG_SHUTTER)
-        mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie);
-
-    if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) {
-        //FIXME: use a canned YUV image!
-        // In the meantime just make another fake camera picture.
-        int w, h;
-        mParameters.getPictureSize(&w, &h);
-        sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h);
-        FakeCamera cam(w, h);
-        cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base());
-        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
-    }
-
-    if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
-        sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
-        sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
-        memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
-        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
-    }
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::takePicture()
-{
-    stopPreview();
-    if (createThread(beginPictureThread, this) == false)
-        return -1;
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::cancelPicture()
-{
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::dump(int fd, const Vector<String16>& args) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    AutoMutex lock(&mLock);
-    if (mFakeCamera != 0) {
-        mFakeCamera->dump(fd);
-        mParameters.dump(fd, args);
-        snprintf(buffer, 255, " preview frame(%d), size (%d), running(%s)\n", mCurrentPreviewFrame, mPreviewFrameSize, mPreviewRunning?"true": "false");
-        result.append(buffer);
-    } else {
-        result.append("No camera client yet.\n");
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t CameraHardwareStub::setParameters(const CameraParameters& params)
-{
-    Mutex::Autolock lock(mLock);
-    // XXX verify params
-
-    if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
-        LOGE("Only yuv422sp preview is supported");
-        return -1;
-    }
-
-    if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
-        LOGE("Only jpeg still pictures are supported");
-        return -1;
-    }
-
-    int w, h;
-    params.getPictureSize(&w, &h);
-    if (w != kCannedJpegWidth && h != kCannedJpegHeight) {
-        LOGE("Still picture size must be size of canned JPEG (%dx%d)",
-             kCannedJpegWidth, kCannedJpegHeight);
-        return -1;
-    }
-
-    mParameters = params;
-    initHeapLocked();
-
-    return NO_ERROR;
-}
-
-CameraParameters CameraHardwareStub::getParameters() const
-{
-    Mutex::Autolock lock(mLock);
-    return mParameters;
-}
-
-status_t CameraHardwareStub::sendCommand(int32_t command, int32_t arg1,
-                                         int32_t arg2)
-{
-    return BAD_VALUE;
-}
-
-void CameraHardwareStub::release()
-{
-}
-
-wp<CameraHardwareInterface> CameraHardwareStub::singleton;
-
-sp<CameraHardwareInterface> CameraHardwareStub::createInstance()
-{
-    if (singleton != 0) {
-        sp<CameraHardwareInterface> hardware = singleton.promote();
-        if (hardware != 0) {
-            return hardware;
-        }
-    }
-    sp<CameraHardwareInterface> hardware(new CameraHardwareStub());
-    singleton = hardware;
-    return hardware;
-}
-
-extern "C" sp<CameraHardwareInterface> openCameraHardware()
-{
-    return CameraHardwareStub::createInstance();
-}
-
-}; // namespace android
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
deleted file mode 100644
index 957813a..0000000
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-**
-** Copyright 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 ANDROID_HARDWARE_CAMERA_HARDWARE_STUB_H
-#define ANDROID_HARDWARE_CAMERA_HARDWARE_STUB_H
-
-#include "FakeCamera.h"
-#include <utils/threads.h>
-#include <camera/CameraHardwareInterface.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class CameraHardwareStub : public CameraHardwareInterface {
-public:
-    virtual sp<IMemoryHeap> getPreviewHeap() const;
-    virtual sp<IMemoryHeap> getRawHeap() const;
-
-    virtual void        setCallbacks(notify_callback notify_cb,
-                                     data_callback data_cb,
-                                     data_callback_timestamp data_cb_timestamp,
-                                     void* user);
-
-    virtual void        enableMsgType(int32_t msgType);
-    virtual void        disableMsgType(int32_t msgType);
-    virtual bool        msgTypeEnabled(int32_t msgType);
-
-    virtual status_t    startPreview();
-    virtual void        stopPreview();
-    virtual bool        previewEnabled();
-
-    virtual status_t    startRecording();
-    virtual void        stopRecording();
-    virtual bool        recordingEnabled();
-    virtual void        releaseRecordingFrame(const sp<IMemory>& mem);
-
-    virtual status_t    autoFocus();
-    virtual status_t    cancelAutoFocus();
-    virtual status_t    takePicture();
-    virtual status_t    cancelPicture();
-    virtual status_t    dump(int fd, const Vector<String16>& args) const;
-    virtual status_t    setParameters(const CameraParameters& params);
-    virtual CameraParameters  getParameters() const;
-    virtual status_t    sendCommand(int32_t command, int32_t arg1,
-                                    int32_t arg2);
-    virtual void release();
-
-    static sp<CameraHardwareInterface> createInstance();
-
-private:
-                        CameraHardwareStub();
-    virtual             ~CameraHardwareStub();
-
-    static wp<CameraHardwareInterface> singleton;
-
-    static const int kBufferCount = 4;
-
-    class PreviewThread : public Thread {
-        CameraHardwareStub* mHardware;
-    public:
-        PreviewThread(CameraHardwareStub* hw) :
-#ifdef SINGLE_PROCESS
-            // In single process mode this thread needs to be a java thread,
-            // since we won't be calling through the binder.
-            Thread(true),
-#else
-            Thread(false),
-#endif
-              mHardware(hw) { }
-        virtual void onFirstRef() {
-            run("CameraPreviewThread", PRIORITY_URGENT_DISPLAY);
-        }
-        virtual bool threadLoop() {
-            mHardware->previewThread();
-            // loop until we need to quit
-            return true;
-        }
-    };
-
-    void initDefaultParameters();
-    void initHeapLocked();
-
-    int previewThread();
-
-    static int beginAutoFocusThread(void *cookie);
-    int autoFocusThread();
-
-    static int beginPictureThread(void *cookie);
-    int pictureThread();
-
-    mutable Mutex       mLock;
-
-    CameraParameters    mParameters;
-
-    sp<MemoryHeapBase>  mPreviewHeap;
-    sp<MemoryHeapBase>  mRawHeap;
-    sp<MemoryBase>      mBuffers[kBufferCount];
-
-    FakeCamera          *mFakeCamera;
-    bool                mPreviewRunning;
-    int                 mPreviewFrameSize;
-
-    // protected by mLock
-    sp<PreviewThread>   mPreviewThread;
-
-    notify_callback    mNotifyCb;
-    data_callback      mDataCb;
-    data_callback_timestamp mDataCbTimestamp;
-    void               *mCallbackCookie;
-
-    int32_t             mMsgEnabled;
-
-    // only used from PreviewThread
-    int                 mCurrentPreviewFrame;
-};
-
-}; // namespace android
-
-#endif
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
deleted file mode 100644
index 118249e..0000000
--- a/camera/libcameraservice/CameraService.cpp
+++ /dev/null
@@ -1,1417 +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.
-*/
-
-#define LOG_TAG "CameraService"
-#include <utils/Log.h>
-
-#include <binder/IServiceManager.h>
-#include <binder/IPCThreadState.h>
-#include <utils/String16.h>
-#include <utils/Errors.h>
-#include <binder/MemoryBase.h>
-#include <binder/MemoryHeapBase.h>
-#include <camera/ICameraService.h>
-#include <surfaceflinger/ISurface.h>
-#include <ui/Overlay.h>
-
-#include <hardware/hardware.h>
-
-#include <media/mediaplayer.h>
-#include <media/AudioSystem.h>
-#include "CameraService.h"
-
-#include <cutils/atomic.h>
-
-namespace android {
-
-extern "C" {
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <pthread.h>
-#include <signal.h>
-}
-
-// When you enable this, as well as DEBUG_REFS=1 and
-// DEBUG_REFS_ENABLED_BY_DEFAULT=0 in libutils/RefBase.cpp, this will track all
-// references to the CameraService::Client in order to catch the case where the
-// client is being destroyed while a callback from the CameraHardwareInterface
-// is outstanding.  This is a serious bug because if we make another call into
-// CameraHardwreInterface that itself triggers a callback, we will deadlock.
-
-#define DEBUG_CLIENT_REFERENCES 0
-
-#define PICTURE_TIMEOUT seconds(5)
-
-#define DEBUG_DUMP_PREVIEW_FRAME_TO_FILE 0 /* n-th frame to write */
-#define DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE 0
-#define DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE 0
-#define DEBUG_DUMP_POSTVIEW_SNAPSHOT_TO_FILE 0
-
-#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
-static int debug_frame_cnt;
-#endif
-
-static int getCallingPid() {
-    return IPCThreadState::self()->getCallingPid();
-}
-
-// ----------------------------------------------------------------------------
-
-void CameraService::instantiate() {
-    defaultServiceManager()->addService(
-            String16("media.camera"), new CameraService());
-}
-
-// ----------------------------------------------------------------------------
-
-CameraService::CameraService() :
-    BnCameraService()
-{
-    LOGI("CameraService started: pid=%d", getpid());
-    mUsers = 0;
-}
-
-CameraService::~CameraService()
-{
-    if (mClient != 0) {
-        LOGE("mClient was still connected in destructor!");
-    }
-}
-
-sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
-{
-    int callingPid = getCallingPid();
-    LOGV("CameraService::connect E (pid %d, client %p)", callingPid,
-            cameraClient->asBinder().get());
-
-    Mutex::Autolock lock(mServiceLock);
-    sp<Client> client;
-    if (mClient != 0) {
-        sp<Client> currentClient = mClient.promote();
-        if (currentClient != 0) {
-            sp<ICameraClient> currentCameraClient(currentClient->getCameraClient());
-            if (cameraClient->asBinder() == currentCameraClient->asBinder()) {
-                // This is the same client reconnecting...
-                LOGV("CameraService::connect X (pid %d, same client %p) is reconnecting...",
-                    callingPid, cameraClient->asBinder().get());
-                return currentClient;
-            } else {
-                // It's another client... reject it
-                LOGV("CameraService::connect X (pid %d, new client %p) rejected. "
-                    "(old pid %d, old client %p)",
-                    callingPid, cameraClient->asBinder().get(),
-                    currentClient->mClientPid, currentCameraClient->asBinder().get());
-                if (kill(currentClient->mClientPid, 0) == -1 && errno == ESRCH) {
-                    LOGV("The old client is dead!");
-                }
-                return client;
-            }
-        } else {
-            // can't promote, the previous client has died...
-            LOGV("New client (pid %d) connecting, old reference was dangling...",
-                    callingPid);
-            mClient.clear();
-        }
-    }
-
-    if (mUsers > 0) {
-        LOGV("Still have client, rejected");
-        return client;
-    }
-
-    // create a new Client object
-    client = new Client(this, cameraClient, callingPid);
-    mClient = client;
-#if DEBUG_CLIENT_REFERENCES
-    // Enable tracking for this object, and track increments and decrements of
-    // the refcount.
-    client->trackMe(true, true);
-#endif
-    LOGV("CameraService::connect X");
-    return client;
-}
-
-void CameraService::removeClient(const sp<ICameraClient>& cameraClient)
-{
-    int callingPid = getCallingPid();
-
-    // Declare this outside the lock to make absolutely sure the
-    // destructor won't be called with the lock held.
-    sp<Client> client;
-
-    Mutex::Autolock lock(mServiceLock);
-
-    if (mClient == 0) {
-        // This happens when we have already disconnected.
-        LOGV("removeClient (pid %d): already disconnected", callingPid);
-        return;
-    }
-
-    // Promote mClient. It can fail if we are called from this path:
-    // Client::~Client() -> disconnect() -> removeClient().
-    client = mClient.promote();
-    if (client == 0) {
-        LOGV("removeClient (pid %d): no more strong reference", callingPid);
-        mClient.clear();
-        return;
-    }
-
-    if (cameraClient->asBinder() != client->getCameraClient()->asBinder()) {
-        // ugh! that's not our client!!
-        LOGW("removeClient (pid %d): mClient doesn't match!", callingPid);
-    } else {
-        // okay, good, forget about mClient
-        mClient.clear();
-    }
-
-    LOGV("removeClient (pid %d) done", callingPid);
-}
-
-// The reason we need this count is a new CameraService::connect() request may
-// come in while the previous Client's destructor has not been run or is still
-// running. If the last strong reference of the previous Client is gone but
-// destructor has not been run, we should not allow the new Client to be created
-// because we need to wait for the previous Client to tear down the hardware
-// first.
-void CameraService::incUsers() {
-    android_atomic_inc(&mUsers);
-}
-
-void CameraService::decUsers() {
-    android_atomic_dec(&mUsers);
-}
-
-static sp<MediaPlayer> newMediaPlayer(const char *file)
-{
-    sp<MediaPlayer> mp = new MediaPlayer();
-    if (mp->setDataSource(file, NULL /* headers */) == NO_ERROR) {
-        mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE);
-        mp->prepare();
-    } else {
-        mp.clear();
-        LOGE("Failed to load CameraService sounds.");
-    }
-    return mp;
-}
-
-CameraService::Client::Client(const sp<CameraService>& cameraService,
-        const sp<ICameraClient>& cameraClient, pid_t clientPid)
-{
-    int callingPid = getCallingPid();
-    LOGV("Client::Client E (pid %d)", callingPid);
-    mCameraService = cameraService;
-    mCameraClient = cameraClient;
-    mClientPid = clientPid;
-    mHardware = openCameraHardware();
-    mUseOverlay = mHardware->useOverlay();
-
-    mHardware->setCallbacks(notifyCallback,
-                            dataCallback,
-                            dataCallbackTimestamp,
-                            mCameraService.get());
-
-    // Enable zoom, error, and focus messages by default
-    mHardware->enableMsgType(CAMERA_MSG_ERROR |
-                             CAMERA_MSG_ZOOM |
-                             CAMERA_MSG_FOCUS);
-
-    mMediaPlayerClick = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
-    mMediaPlayerBeep = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
-    mOverlayW = 0;
-    mOverlayH = 0;
-
-    // Callback is disabled by default
-    mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
-    mOrientation = 0;
-    cameraService->incUsers();
-    LOGV("Client::Client X (pid %d)", callingPid);
-}
-
-status_t CameraService::Client::checkPid()
-{
-    int callingPid = getCallingPid();
-    if (mClientPid == callingPid) return NO_ERROR;
-    LOGW("Attempt to use locked camera (client %p) from different process "
-        " (old pid %d, new pid %d)",
-        getCameraClient()->asBinder().get(), mClientPid, callingPid);
-    return -EBUSY;
-}
-
-status_t CameraService::Client::lock()
-{
-    int callingPid = getCallingPid();
-    LOGV("lock from pid %d (mClientPid %d)", callingPid, mClientPid);
-    Mutex::Autolock _l(mLock);
-    // lock camera to this client if the the camera is unlocked
-    if (mClientPid == 0) {
-        mClientPid = callingPid;
-        return NO_ERROR;
-    }
-    // returns NO_ERROR if the client already owns the camera, -EBUSY otherwise
-    return checkPid();
-}
-
-status_t CameraService::Client::unlock()
-{
-    int callingPid = getCallingPid();
-    LOGV("unlock from pid %d (mClientPid %d)", callingPid, mClientPid);
-    Mutex::Autolock _l(mLock);
-    // allow anyone to use camera
-    status_t result = checkPid();
-    if (result == NO_ERROR) {
-        mClientPid = 0;
-        LOGV("clear mCameraClient (pid %d)", callingPid);
-        // we need to remove the reference so that when app goes
-        // away, the reference count goes to 0.
-        mCameraClient.clear();
-    }
-    return result;
-}
-
-status_t CameraService::Client::connect(const sp<ICameraClient>& client)
-{
-    int callingPid = getCallingPid();
-
-    // connect a new process to the camera
-    LOGV("Client::connect E (pid %d, client %p)", callingPid, client->asBinder().get());
-
-    // I hate this hack, but things get really ugly when the media recorder
-    // service is handing back the camera to the app. The ICameraClient
-    // destructor will be called during the same IPC, making it look like
-    // the remote client is trying to disconnect. This hack temporarily
-    // sets the mClientPid to an invalid pid to prevent the hardware from
-    // being torn down.
-    {
-
-        // hold a reference to the old client or we will deadlock if the client is
-        // in the same process and we hold the lock when we remove the reference
-        sp<ICameraClient> oldClient;
-        {
-            Mutex::Autolock _l(mLock);
-            if (mClientPid != 0 && checkPid() != NO_ERROR) {
-                LOGW("Tried to connect to locked camera (old pid %d, new pid %d)",
-                        mClientPid, callingPid);
-                return -EBUSY;
-            }
-            oldClient = mCameraClient;
-
-            // did the client actually change?
-            if ((mCameraClient != NULL) && (client->asBinder() == mCameraClient->asBinder())) {
-                LOGV("Connect to the same client");
-                return NO_ERROR;
-            }
-
-            mCameraClient = client;
-            mClientPid = -1;
-            mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
-            LOGV("Connect to the new client (pid %d, client %p)",
-                callingPid, mCameraClient->asBinder().get());
-        }
-
-    }
-    // the old client destructor is called when oldClient goes out of scope
-    // now we set the new PID to lock the interface again
-    mClientPid = callingPid;
-
-    return NO_ERROR;
-}
-
-#if HAVE_ANDROID_OS
-static void *unregister_surface(void *arg)
-{
-    ISurface *surface = (ISurface *)arg;
-    surface->unregisterBuffers();
-    IPCThreadState::self()->flushCommands();
-    return NULL;
-}
-#endif
-
-CameraService::Client::~Client()
-{
-    int callingPid = getCallingPid();
-
-    // tear down client
-    LOGV("Client::~Client E (pid %d, client %p)",
-            callingPid, getCameraClient()->asBinder().get());
-    if (mSurface != 0 && !mUseOverlay) {
-#if HAVE_ANDROID_OS
-        pthread_t thr;
-        // We unregister the buffers in a different thread because binder does
-        // not let us make sychronous transactions in a binder destructor (that
-        // is, upon our reaching a refcount of zero.)
-        pthread_create(&thr, NULL,
-                       unregister_surface,
-                       mSurface.get());
-        pthread_join(thr, NULL);
-#else
-        mSurface->unregisterBuffers();
-#endif
-    }
-
-    if (mMediaPlayerBeep.get() != NULL) {
-        mMediaPlayerBeep->disconnect();
-        mMediaPlayerBeep.clear();
-    }
-    if (mMediaPlayerClick.get() != NULL) {
-        mMediaPlayerClick->disconnect();
-        mMediaPlayerClick.clear();
-    }
-
-    // make sure we tear down the hardware
-    mClientPid = callingPid;
-    disconnect();
-    LOGV("Client::~Client X (pid %d)", mClientPid);
-}
-
-void CameraService::Client::disconnect()
-{
-    int callingPid = getCallingPid();
-
-    LOGV("Client::disconnect() E (pid %d client %p)",
-            callingPid, getCameraClient()->asBinder().get());
-
-    Mutex::Autolock lock(mLock);
-    if (mClientPid <= 0) {
-        LOGV("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
-        return;
-    }
-    if (checkPid() != NO_ERROR) {
-        LOGV("Different client - don't disconnect");
-        return;
-    }
-
-    // Make sure disconnect() is done once and once only, whether it is called
-    // from the user directly, or called by the destructor.
-    if (mHardware == 0) return;
-
-    LOGV("hardware teardown");
-    // Before destroying mHardware, we must make sure it's in the
-    // idle state.
-    mHardware->stopPreview();
-    // Cancel all picture callbacks.
-    mHardware->disableMsgType(CAMERA_MSG_SHUTTER |
-                              CAMERA_MSG_POSTVIEW_FRAME |
-                              CAMERA_MSG_RAW_IMAGE |
-                              CAMERA_MSG_COMPRESSED_IMAGE);
-    mHardware->cancelPicture();
-    // Turn off remaining messages.
-    mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS);
-    // Release the hardware resources.
-    mHardware->release();
-    // Release the held overlay resources.
-    if (mUseOverlay)
-    {
-        mOverlayRef = 0;
-    }
-    mHardware.clear();
-
-    mCameraService->removeClient(mCameraClient);
-    mCameraService->decUsers();
-
-    LOGV("Client::disconnect() X (pid %d)", callingPid);
-}
-
-// pass the buffered ISurface to the camera service
-status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
-{
-    LOGV("setPreviewDisplay(%p) (pid %d)",
-         ((surface == NULL) ? NULL : surface.get()), getCallingPid());
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    Mutex::Autolock surfaceLock(mSurfaceLock);
-    result = NO_ERROR;
-    // asBinder() is safe on NULL (returns NULL)
-    if (surface->asBinder() != mSurface->asBinder()) {
-        if (mSurface != 0) {
-            LOGV("clearing old preview surface %p", mSurface.get());
-            if ( !mUseOverlay)
-            {
-                mSurface->unregisterBuffers();
-            }
-            else
-            {
-                // Force the destruction of any previous overlay
-                sp<Overlay> dummy;
-                mHardware->setOverlay( dummy );
-            }
-        }
-        mSurface = surface;
-        mOverlayRef = 0;
-        // If preview has been already started, set overlay or register preview
-        // buffers now.
-        if (mHardware->previewEnabled()) {
-            if (mUseOverlay) {
-                result = setOverlay();
-            } else if (mSurface != 0) {
-                result = registerPreviewBuffers();
-            }
-        }
-    }
-    return result;
-}
-
-// set the preview callback flag to affect how the received frames from
-// preview are handled.
-void CameraService::Client::setPreviewCallbackFlag(int callback_flag)
-{
-    LOGV("setPreviewCallbackFlag (pid %d)", getCallingPid());
-    Mutex::Autolock lock(mLock);
-    if (checkPid() != NO_ERROR) return;
-    mPreviewCallbackFlag = callback_flag;
-
-    if(mUseOverlay) {
-        if(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)
-            mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        else
-            mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-    }
-}
-
-// start preview mode
-status_t CameraService::Client::startCameraMode(camera_mode mode)
-{
-    int callingPid = getCallingPid();
-
-    LOGV("startCameraMode(%d) (pid %d)", mode, callingPid);
-
-    /* we cannot call into mHardware with mLock held because
-     * mHardware has callbacks onto us which acquire this lock
-     */
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return INVALID_OPERATION;
-    }
-
-    switch(mode) {
-    case CAMERA_RECORDING_MODE:
-        if (mSurface == 0) {
-            LOGE("setPreviewDisplay must be called before startRecordingMode.");
-            return INVALID_OPERATION;
-        }
-        return startRecordingMode();
-
-    default: // CAMERA_PREVIEW_MODE
-        if (mSurface == 0) {
-            LOGV("mSurface is not set yet.");
-        }
-        return startPreviewMode();
-    }
-}
-
-status_t CameraService::Client::startRecordingMode()
-{
-    LOGV("startRecordingMode (pid %d)", getCallingPid());
-
-    status_t ret = UNKNOWN_ERROR;
-
-    // if preview has not been started, start preview first
-    if (!mHardware->previewEnabled()) {
-        ret = startPreviewMode();
-        if (ret != NO_ERROR) {
-            return ret;
-        }
-    }
-
-    // if recording has been enabled, nothing needs to be done
-    if (mHardware->recordingEnabled()) {
-        return NO_ERROR;
-    }
-
-    // start recording mode
-    ret = mHardware->startRecording();
-    if (ret != NO_ERROR) {
-        LOGE("mHardware->startRecording() failed with status %d", ret);
-    }
-    return ret;
-}
-
-status_t CameraService::Client::setOverlay()
-{
-    LOGV("setOverlay");
-    int w, h;
-    CameraParameters params(mHardware->getParameters());
-    params.getPreviewSize(&w, &h);
-
-    if ( w != mOverlayW || h != mOverlayH )
-    {
-        // Force the destruction of any previous overlay
-        sp<Overlay> dummy;
-        mHardware->setOverlay( dummy );
-        mOverlayRef = 0;
-    }
-
-    status_t ret = NO_ERROR;
-    if (mSurface != 0) {
-        if (mOverlayRef.get() == NULL) {
-
-            // FIXME:
-            // Surfaceflinger may hold onto the previous overlay reference for some
-            // time after we try to destroy it. retry a few times. In the future, we
-            // should make the destroy call block, or possibly specify that we can
-            // wait in the createOverlay call if the previous overlay is in the 
-            // process of being destroyed.
-            for (int retry = 0; retry < 50; ++retry) {
-                mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT,
-                                                      mOrientation);
-                if (mOverlayRef != NULL) break;
-                LOGW("Overlay create failed - retrying");
-                usleep(20000);
-            }
-            if ( mOverlayRef.get() == NULL )
-            {
-                LOGE("Overlay Creation Failed!");
-                return -EINVAL;
-            }
-            ret = mHardware->setOverlay(new Overlay(mOverlayRef));
-        }
-    } else {
-        ret = mHardware->setOverlay(NULL);
-    }
-    if (ret != NO_ERROR) {
-        LOGE("mHardware->setOverlay() failed with status %d\n", ret);
-    }
-
-    mOverlayW = w;
-    mOverlayH = h;
-
-    return ret;
-}
-
-status_t CameraService::Client::registerPreviewBuffers()
-{
-    int w, h;
-    CameraParameters params(mHardware->getParameters());
-    params.getPreviewSize(&w, &h);
-
-    // don't use a hardcoded format here
-    ISurface::BufferHeap buffers(w, h, w, h,
-                                 HAL_PIXEL_FORMAT_YCrCb_420_SP,
-                                 mOrientation,
-                                 0,
-                                 mHardware->getPreviewHeap());
-
-    status_t ret = mSurface->registerBuffers(buffers);
-    if (ret != NO_ERROR) {
-        LOGE("registerBuffers failed with status %d", ret);
-    }
-    return ret;
-}
-
-status_t CameraService::Client::startPreviewMode()
-{
-    LOGV("startPreviewMode (pid %d)", getCallingPid());
-
-    // if preview has been enabled, nothing needs to be done
-    if (mHardware->previewEnabled()) {
-        return NO_ERROR;
-    }
-
-    // start preview mode
-#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
-    debug_frame_cnt = 0;
-#endif
-    status_t ret = NO_ERROR;
-
-    if (mUseOverlay) {
-        // If preview display has been set, set overlay now.
-        if (mSurface != 0) {
-            ret = setOverlay();
-        }
-        if (ret != NO_ERROR) return ret;
-        ret = mHardware->startPreview();
-    } else {
-        mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        ret = mHardware->startPreview();
-        if (ret != NO_ERROR) return ret;
-        // If preview display has been set, register preview buffers now.
-        if (mSurface != 0) {
-           // Unregister here because the surface registered with raw heap.
-           mSurface->unregisterBuffers();
-           ret = registerPreviewBuffers();
-        }
-    }
-    return ret;
-}
-
-status_t CameraService::Client::startPreview()
-{
-    LOGV("startPreview (pid %d)", getCallingPid());
-
-    return startCameraMode(CAMERA_PREVIEW_MODE);
-}
-
-status_t CameraService::Client::startRecording()
-{
-    LOGV("startRecording (pid %d)", getCallingPid());
-
-    if (mMediaPlayerBeep.get() != NULL) {
-        // do not play record jingle if stream volume is 0
-        // (typically because ringer mode is silent).
-        int index;
-        AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
-        if (index != 0) {
-            mMediaPlayerBeep->seekTo(0);
-            mMediaPlayerBeep->start();
-        }
-    }
-
-    mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME);
-
-    return startCameraMode(CAMERA_RECORDING_MODE);
-}
-
-// stop preview mode
-void CameraService::Client::stopPreview()
-{
-    LOGV("stopPreview (pid %d)", getCallingPid());
-
-    // hold main lock during state transition
-    {
-        Mutex::Autolock lock(mLock);
-        if (checkPid() != NO_ERROR) return;
-
-        if (mHardware == 0) {
-            LOGE("mHardware is NULL, returning.");
-            return;
-        }
-
-        mHardware->stopPreview();
-        mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-        LOGV("stopPreview(), hardware stopped OK");
-
-        if (mSurface != 0 && !mUseOverlay) {
-            mSurface->unregisterBuffers();
-        }
-    }
-
-    // hold preview buffer lock
-    {
-        Mutex::Autolock lock(mPreviewLock);
-        mPreviewBuffer.clear();
-    }
-}
-
-// stop recording mode
-void CameraService::Client::stopRecording()
-{
-    LOGV("stopRecording (pid %d)", getCallingPid());
-
-    // hold main lock during state transition
-    {
-        Mutex::Autolock lock(mLock);
-        if (checkPid() != NO_ERROR) return;
-
-        if (mHardware == 0) {
-            LOGE("mHardware is NULL, returning.");
-            return;
-        }
-
-        if (mMediaPlayerBeep.get() != NULL) {
-            mMediaPlayerBeep->seekTo(0);
-            mMediaPlayerBeep->start();
-        }
-
-        mHardware->stopRecording();
-        mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME);
-        LOGV("stopRecording(), hardware stopped OK");
-    }
-
-    // hold preview buffer lock
-    {
-        Mutex::Autolock lock(mPreviewLock);
-        mPreviewBuffer.clear();
-    }
-}
-
-// release a recording frame
-void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem)
-{
-    Mutex::Autolock lock(mLock);
-    if (checkPid() != NO_ERROR) return;
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return;
-    }
-
-    mHardware->releaseRecordingFrame(mem);
-}
-
-bool CameraService::Client::previewEnabled()
-{
-    Mutex::Autolock lock(mLock);
-    if (mHardware == 0) return false;
-    return mHardware->previewEnabled();
-}
-
-bool CameraService::Client::recordingEnabled()
-{
-    Mutex::Autolock lock(mLock);
-    if (mHardware == 0) return false;
-    return mHardware->recordingEnabled();
-}
-
-// Safely retrieves a strong pointer to the client during a hardware callback.
-sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user)
-{
-    sp<Client> client = 0;
-    CameraService *service = static_cast<CameraService*>(user);
-    if (service != NULL) {
-        Mutex::Autolock ourLock(service->mServiceLock);
-        if (service->mClient != 0) {
-            client = service->mClient.promote();
-            if (client == 0) {
-                LOGE("getClientFromCookie: client appears to have died");
-                service->mClient.clear();
-            }
-        } else {
-            LOGE("getClientFromCookie: got callback but client was NULL");
-        }
-    }
-    return client;
-}
-
-
-#if DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE || \
-    DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE || \
-    DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
-static void dump_to_file(const char *fname,
-                         uint8_t *buf, uint32_t size)
-{
-    int nw, cnt = 0;
-    uint32_t written = 0;
-
-    LOGV("opening file [%s]\n", fname);
-    int fd = open(fname, O_RDWR | O_CREAT);
-    if (fd < 0) {
-        LOGE("failed to create file [%s]: %s", fname, strerror(errno));
-        return;
-    }
-
-    LOGV("writing %d bytes to file [%s]\n", size, fname);
-    while (written < size) {
-        nw = ::write(fd,
-                     buf + written,
-                     size - written);
-        if (nw < 0) {
-            LOGE("failed to write to file [%s]: %s",
-                 fname, strerror(errno));
-            break;
-        }
-        written += nw;
-        cnt++;
-    }
-    LOGV("done writing %d bytes to file [%s] in %d passes\n",
-         size, fname, cnt);
-    ::close(fd);
-}
-#endif
-
-status_t CameraService::Client::autoFocus()
-{
-    LOGV("autoFocus (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return INVALID_OPERATION;
-    }
-
-    return mHardware->autoFocus();
-}
-
-status_t CameraService::Client::cancelAutoFocus()
-{
-    LOGV("cancelAutoFocus (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return INVALID_OPERATION;
-    }
-
-    return mHardware->cancelAutoFocus();
-}
-
-// take a picture - image is returned in callback
-status_t CameraService::Client::takePicture()
-{
-    LOGV("takePicture (pid %d)", getCallingPid());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return INVALID_OPERATION;
-    }
-
-    mHardware->enableMsgType(CAMERA_MSG_SHUTTER |
-                             CAMERA_MSG_POSTVIEW_FRAME |
-                             CAMERA_MSG_RAW_IMAGE |
-                             CAMERA_MSG_COMPRESSED_IMAGE);
-
-    return mHardware->takePicture();
-}
-
-// snapshot taken
-void CameraService::Client::handleShutter(
-    image_rect_type *size // The width and height of yuv picture for
-                          // registerBuffer. If this is NULL, use the picture
-                          // size from parameters.
-)
-{
-    // Play shutter sound.
-    if (mMediaPlayerClick.get() != NULL) {
-        // do not play shutter sound if stream volume is 0
-        // (typically because ringer mode is silent).
-        int index;
-        AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index);
-        if (index != 0) {
-            mMediaPlayerClick->seekTo(0);
-            mMediaPlayerClick->start();
-        }
-    }
-
-    // Screen goes black after the buffer is unregistered.
-    if (mSurface != 0 && !mUseOverlay) {
-        mSurface->unregisterBuffers();
-    }
-
-    sp<ICameraClient> c = mCameraClient;
-    if (c != NULL) {
-        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
-    }
-    mHardware->disableMsgType(CAMERA_MSG_SHUTTER);
-
-    // It takes some time before yuvPicture callback to be called.
-    // Register the buffer for raw image here to reduce latency.
-    if (mSurface != 0 && !mUseOverlay) {
-        int w, h;
-        CameraParameters params(mHardware->getParameters());
-        if (size == NULL) {
-            params.getPictureSize(&w, &h);
-        } else {
-            w = size->width;
-            h = size->height;
-            w &= ~1;
-            h &= ~1;
-            LOGV("Snapshot image width=%d, height=%d", w, h);
-        }
-        // FIXME: don't use hardcoded format constants here
-        ISurface::BufferHeap buffers(w, h, w, h,
-            HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0,
-            mHardware->getRawHeap());
-
-        mSurface->registerBuffers(buffers);
-        IPCThreadState::self()->flushCommands();
-    }
-}
-
-// preview callback - frame buffer update
-void CameraService::Client::handlePreviewData(const sp<IMemory>& mem)
-{
-    ssize_t offset;
-    size_t size;
-    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-
-#if DEBUG_HEAP_LEAKS && 0 // debugging
-    if (gWeakHeap == NULL) {
-        if (gWeakHeap != heap) {
-            LOGV("SETTING PREVIEW HEAP");
-            heap->trackMe(true, true);
-            gWeakHeap = heap;
-        }
-    }
-#endif
-#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
-    {
-        if (debug_frame_cnt++ == DEBUG_DUMP_PREVIEW_FRAME_TO_FILE) {
-            dump_to_file("/data/preview.yuv",
-                         (uint8_t *)heap->base() + offset, size);
-        }
-    }
-#endif
-
-    if (!mUseOverlay)
-    {
-        Mutex::Autolock surfaceLock(mSurfaceLock);
-        if (mSurface != NULL) {
-            mSurface->postBuffer(offset);
-        }
-    }
-
-    // local copy of the callback flags
-    int flags = mPreviewCallbackFlag;
-
-    // is callback enabled?
-    if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
-        // If the enable bit is off, the copy-out and one-shot bits are ignored
-        LOGV("frame callback is diabled");
-        return;
-    }
-
-    // hold a strong pointer to the client
-    sp<ICameraClient> c = mCameraClient;
-
-    // clear callback flags if no client or one-shot mode
-    if ((c == NULL) || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
-        LOGV("Disable preview callback");
-        mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
-                                FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
-                                FRAME_CALLBACK_FLAG_ENABLE_MASK);
-        // TODO: Shouldn't we use this API for non-overlay hardware as well?
-        if (mUseOverlay)
-            mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
-    }
-
-    // Is the received frame copied out or not?
-    if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
-        LOGV("frame is copied");
-        copyFrameAndPostCopiedFrame(c, heap, offset, size);
-    } else {
-        LOGV("frame is forwarded");
-        c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem);
-    }
-}
-
-// picture callback - postview image ready
-void CameraService::Client::handlePostview(const sp<IMemory>& mem)
-{
-#if DEBUG_DUMP_POSTVIEW_SNAPSHOT_TO_FILE // for testing pursposes only
-    {
-        ssize_t offset;
-        size_t size;
-        sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-        dump_to_file("/data/postview.yuv",
-                     (uint8_t *)heap->base() + offset, size);
-    }
-#endif
-
-    sp<ICameraClient> c = mCameraClient;
-    if (c != NULL) {
-        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem);
-    }
-    mHardware->disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
-}
-
-// picture callback - raw image ready
-void CameraService::Client::handleRawPicture(const sp<IMemory>& mem)
-{
-    ssize_t offset;
-    size_t size;
-    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-#if DEBUG_HEAP_LEAKS && 0 // debugging
-    gWeakHeap = heap; // debugging
-#endif
-
-    //LOGV("handleRawPicture(%d, %d)", offset, size);
-#if DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE // for testing pursposes only
-    dump_to_file("/data/photo.yuv",
-                 (uint8_t *)heap->base() + offset, size);
-#endif
-
-    // Put the YUV version of the snapshot in the preview display.
-    if (mSurface != 0 && !mUseOverlay) {
-        mSurface->postBuffer(offset);
-    }
-
-    sp<ICameraClient> c = mCameraClient;
-    if (c != NULL) {
-        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem);
-    }
-    mHardware->disableMsgType(CAMERA_MSG_RAW_IMAGE);
-}
-
-// picture callback - compressed picture ready
-void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem)
-{
-#if DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE // for testing pursposes only
-    {
-        ssize_t offset;
-        size_t size;
-        sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
-        dump_to_file("/data/photo.jpg",
-                     (uint8_t *)heap->base() + offset, size);
-    }
-#endif
-
-    sp<ICameraClient> c = mCameraClient;
-    if (c != NULL) {
-        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem);
-    }
-    mHardware->disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
-}
-
-void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user)
-{
-    LOGV("notifyCallback(%d)", msgType);
-
-    sp<Client> client = getClientFromCookie(user);
-    if (client == 0) {
-        return;
-    }
-
-    switch (msgType) {
-        case CAMERA_MSG_SHUTTER:
-            // ext1 is the dimension of the yuv picture.
-            client->handleShutter((image_rect_type *)ext1);
-            break;
-        default:
-            sp<ICameraClient> c = client->mCameraClient;
-            if (c != NULL) {
-                c->notifyCallback(msgType, ext1, ext2);
-            }
-            break;
-    }
-
-#if DEBUG_CLIENT_REFERENCES
-    if (client->getStrongCount() == 1) {
-        LOGE("++++++++++++++++ (NOTIFY CALLBACK) THIS WILL CAUSE A LOCKUP!");
-        client->printRefs();
-    }
-#endif
-}
-
-void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user)
-{
-    LOGV("dataCallback(%d)", msgType);
-
-    sp<Client> client = getClientFromCookie(user);
-    if (client == 0) {
-        return;
-    }
-
-    sp<ICameraClient> c = client->mCameraClient;
-    if (dataPtr == NULL) {
-        LOGE("Null data returned in data callback");
-        if (c != NULL) {
-            c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
-            c->dataCallback(msgType, NULL);
-        }
-        return;
-    }
-
-    switch (msgType) {
-        case CAMERA_MSG_PREVIEW_FRAME:
-            client->handlePreviewData(dataPtr);
-            break;
-        case CAMERA_MSG_POSTVIEW_FRAME:
-            client->handlePostview(dataPtr);
-            break;
-        case CAMERA_MSG_RAW_IMAGE:
-            client->handleRawPicture(dataPtr);
-            break;
-        case CAMERA_MSG_COMPRESSED_IMAGE:
-            client->handleCompressedPicture(dataPtr);
-            break;
-        default:
-            if (c != NULL) {
-                c->dataCallback(msgType, dataPtr);
-            }
-            break;
-    }
-
-#if DEBUG_CLIENT_REFERENCES
-    if (client->getStrongCount() == 1) {
-        LOGE("++++++++++++++++ (DATA CALLBACK) THIS WILL CAUSE A LOCKUP!");
-        client->printRefs();
-    }
-#endif
-}
-
-void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
-                                                  const sp<IMemory>& dataPtr, void* user)
-{
-    LOGV("dataCallbackTimestamp(%d)", msgType);
-
-    sp<Client> client = getClientFromCookie(user);
-    if (client == 0) {
-        return;
-    }
-    sp<ICameraClient> c = client->mCameraClient;
-
-    if (dataPtr == NULL) {
-        LOGE("Null data returned in data with timestamp callback");
-        if (c != NULL) {
-            c->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
-            c->dataCallbackTimestamp(0, msgType, NULL);
-        }
-        return;
-    }
-
-    if (c != NULL) {
-        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
-    }
-
-#if DEBUG_CLIENT_REFERENCES
-    if (client->getStrongCount() == 1) {
-        LOGE("++++++++++++++++ (DATA CALLBACK TIMESTAMP) THIS WILL CAUSE A LOCKUP!");
-        client->printRefs();
-    }
-#endif
-}
-
-// set preview/capture parameters - key/value pairs
-status_t CameraService::Client::setParameters(const String8& params)
-{
-    LOGV("setParameters(%s)", params.string());
-
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return INVALID_OPERATION;
-    }
-
-    CameraParameters p(params);
-
-    return mHardware->setParameters(p);
-}
-
-// get preview/capture parameters - key/value pairs
-String8 CameraService::Client::getParameters() const
-{
-    Mutex::Autolock lock(mLock);
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return String8();
-    }
-
-    String8 params(mHardware->getParameters().flatten());
-    LOGV("getParameters(%s)", params.string());
-    return params;
-}
-
-status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
-{
-    LOGV("sendCommand (pid %d)", getCallingPid());
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPid();
-    if (result != NO_ERROR) return result;
-
-    if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
-        // The orientation cannot be set during preview.
-        if (mHardware->previewEnabled()) {
-            return INVALID_OPERATION;
-        }
-        switch (arg1) {
-            case 0:
-                mOrientation = ISurface::BufferHeap::ROT_0;
-                break;
-            case 90:
-                mOrientation = ISurface::BufferHeap::ROT_90;
-                break;
-            case 180:
-                mOrientation = ISurface::BufferHeap::ROT_180;
-                break;
-            case 270:
-                mOrientation = ISurface::BufferHeap::ROT_270;
-                break;
-            default:
-                return BAD_VALUE;
-        }
-        return OK;
-    }
-
-    if (mHardware == 0) {
-        LOGE("mHardware is NULL, returning.");
-        return INVALID_OPERATION;
-    }
-
-    return mHardware->sendCommand(cmd, arg1, arg2);
-}
-
-void CameraService::Client::copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
-        const sp<IMemoryHeap>& heap, size_t offset, size_t size)
-{
-    LOGV("copyFrameAndPostCopiedFrame");
-    // It is necessary to copy out of pmem before sending this to
-    // the callback. For efficiency, reuse the same MemoryHeapBase
-    // provided it's big enough. Don't allocate the memory or
-    // perform the copy if there's no callback.
-
-    // hold the preview lock while we grab a reference to the preview buffer
-    sp<MemoryHeapBase> previewBuffer;
-    {
-        Mutex::Autolock lock(mPreviewLock);
-        if (mPreviewBuffer == 0) {
-            mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
-        } else if (size > mPreviewBuffer->virtualSize()) {
-            mPreviewBuffer.clear();
-            mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
-        }
-        if (mPreviewBuffer == 0) {
-            LOGE("failed to allocate space for preview buffer");
-            return;
-        }
-        previewBuffer = mPreviewBuffer;
-    }
-    memcpy(previewBuffer->base(),
-           (uint8_t *)heap->base() + offset, size);
-
-    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
-    if (frame == 0) {
-        LOGE("failed to allocate space for frame callback");
-        return;
-    }
-    client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame);
-}
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 60000;
-
-static bool tryLock(Mutex& mutex)
-{
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleep);
-    }
-    return locked;
-}
-
-status_t CameraService::dump(int fd, const Vector<String16>& args)
-{
-    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
-
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        snprintf(buffer, SIZE, "Permission Denial: "
-                "can't dump CameraService from pid=%d, uid=%d\n",
-                getCallingPid(),
-                IPCThreadState::self()->getCallingUid());
-        result.append(buffer);
-        write(fd, result.string(), result.size());
-    } else {
-        bool locked = tryLock(mServiceLock);
-        // failed to lock - CameraService is probably deadlocked
-        if (!locked) {
-            String8 result(kDeadlockedString);
-            write(fd, result.string(), result.size());
-        }
-
-        if (mClient != 0) {
-            sp<Client> currentClient = mClient.promote();
-            sprintf(buffer, "Client (%p) PID: %d\n",
-                    currentClient->getCameraClient()->asBinder().get(),
-                    currentClient->mClientPid);
-            result.append(buffer);
-            write(fd, result.string(), result.size());
-            currentClient->mHardware->dump(fd, args);
-        } else {
-            result.append("No camera client yet.\n");
-            write(fd, result.string(), result.size());
-        }
-
-        if (locked) mServiceLock.unlock();
-    }
-    return NO_ERROR;
-}
-
-
-status_t CameraService::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    // permission checks...
-    switch (code) {
-        case BnCameraService::CONNECT:
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int self_pid = getpid();
-            if (pid != self_pid) {
-                // we're called from a different process, do the real check
-                if (!checkCallingPermission(
-                        String16("android.permission.CAMERA")))
-                {
-                    const int uid = ipc->getCallingUid();
-                    LOGE("Permission Denial: "
-                            "can't use the camera pid=%d, uid=%d", pid, uid);
-                    return PERMISSION_DENIED;
-                }
-            }
-            break;
-    }
-
-    status_t err = BnCameraService::onTransact(code, data, reply, flags);
-
-#if DEBUG_HEAP_LEAKS
-    LOGV("+++ onTransact err %d code %d", err, code);
-
-    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
-        // the 'service' command interrogates this binder for its name, and then supplies it
-        // even for the debugging commands.  that means we need to check for it here, using
-        // ISurfaceComposer (since we delegated the INTERFACE_TRANSACTION handling to
-        // BnSurfaceComposer before falling through to this code).
-
-        LOGV("+++ onTransact code %d", code);
-
-        CHECK_INTERFACE(ICameraService, data, reply);
-
-        switch(code) {
-        case 1000:
-        {
-            if (gWeakHeap != 0) {
-                sp<IMemoryHeap> h = gWeakHeap.promote();
-                IMemoryHeap *p = gWeakHeap.unsafe_get();
-                LOGV("CHECKING WEAK REFERENCE %p (%p)", h.get(), p);
-                if (h != 0)
-                    h->printRefs();
-                bool attempt_to_delete = data.readInt32() == 1;
-                if (attempt_to_delete) {
-                    // NOT SAFE!
-                    LOGV("DELETING WEAK REFERENCE %p (%p)", h.get(), p);
-                    if (p) delete p;
-                }
-                return NO_ERROR;
-            }
-        }
-        break;
-        default:
-            break;
-        }
-    }
-#endif // DEBUG_HEAP_LEAKS
-
-    return err;
-}
-
-}; // namespace android
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
deleted file mode 100644
index 75e96c6..0000000
--- a/camera/libcameraservice/CameraService.h
+++ /dev/null
@@ -1,226 +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 ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
-#define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
-
-#include <camera/ICameraService.h>
-#include <camera/CameraHardwareInterface.h>
-#include <camera/Camera.h>
-
-namespace android {
-
-class MemoryHeapBase;
-class MediaPlayer;
-
-// ----------------------------------------------------------------------------
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// When enabled, this feature allows you to send an event to the CameraService
-// so that you can cause all references to the heap object gWeakHeap, defined
-// below, to be printed. You will also need to set DEBUG_REFS=1 and
-// DEBUG_REFS_ENABLED_BY_DEFAULT=0 in libutils/RefBase.cpp. You just have to
-// set gWeakHeap to the appropriate heap you want to track.
-
-#define DEBUG_HEAP_LEAKS 0
-
-// ----------------------------------------------------------------------------
-
-class CameraService : public BnCameraService
-{
-    class Client;
-
-public:
-    static void instantiate();
-
-    // ICameraService interface
-    virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient);
-
-    virtual status_t        dump(int fd, const Vector<String16>& args);
-
-            void            removeClient(const sp<ICameraClient>& cameraClient);
-
-    virtual status_t onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-
-private:
-
-// ----------------------------------------------------------------------------
-
-    class Client : public BnCamera {
-
-    public:
-        virtual void            disconnect();
-
-        // connect new client with existing camera remote
-        virtual status_t        connect(const sp<ICameraClient>& client);
-
-        // prevent other processes from using this ICamera interface
-        virtual status_t        lock();
-
-        // allow other processes to use this ICamera interface
-        virtual status_t        unlock();
-
-        // pass the buffered ISurface to the camera service
-        virtual status_t        setPreviewDisplay(const sp<ISurface>& surface);
-
-        // set the preview callback flag to affect how the received frames from
-        // preview are handled.
-        virtual void            setPreviewCallbackFlag(int callback_flag);
-
-        // start preview mode, must call setPreviewDisplay first
-        virtual status_t        startPreview();
-
-        // stop preview mode
-        virtual void            stopPreview();
-
-        // get preview state
-        virtual bool            previewEnabled();
-
-        // start recording mode
-        virtual status_t        startRecording();
-
-        // stop recording mode
-        virtual void            stopRecording();
-
-        // get recording state
-        virtual bool            recordingEnabled();
-
-        // release a recording frame
-        virtual void            releaseRecordingFrame(const sp<IMemory>& mem);
-
-        // auto focus
-        virtual status_t        autoFocus();
-
-        // cancel auto focus
-        virtual status_t        cancelAutoFocus();
-
-        // take a picture - returns an IMemory (ref-counted mmap)
-        virtual status_t        takePicture();
-
-        // set preview/capture parameters - key/value pairs
-        virtual status_t        setParameters(const String8& params);
-
-        // get preview/capture parameters - key/value pairs
-        virtual String8         getParameters() const;
-
-        // send command to camera driver
-        virtual status_t        sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);
-
-        // our client...
-        const sp<ICameraClient>&    getCameraClient() const { return mCameraClient; }
-
-    private:
-        friend class CameraService;
-                                Client(const sp<CameraService>& cameraService,
-                                        const sp<ICameraClient>& cameraClient,
-                                        pid_t clientPid);
-                                Client();
-        virtual                 ~Client();
-
-                    status_t    checkPid();
-
-        static      void        notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
-        static      void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
-        static      void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
-                                                      const sp<IMemory>& dataPtr, void* user);
-
-        static      sp<Client>  getClientFromCookie(void* user);
-
-                    void        handlePreviewData(const sp<IMemory>&);
-                    void        handleShutter(image_rect_type *image);
-                    void        handlePostview(const sp<IMemory>&);
-                    void        handleRawPicture(const sp<IMemory>&);
-                    void        handleCompressedPicture(const sp<IMemory>&);
-
-                    void        copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
-                                    const sp<IMemoryHeap>& heap, size_t offset, size_t size);
-
-        // camera operation mode
-        enum camera_mode {
-            CAMERA_PREVIEW_MODE   = 0,  // frame automatically released
-            CAMERA_RECORDING_MODE = 1,  // frame has to be explicitly released by releaseRecordingFrame()
-        };
-        status_t                startCameraMode(camera_mode mode);
-        status_t                startPreviewMode();
-        status_t                startRecordingMode();
-        status_t                setOverlay();
-        status_t                registerPreviewBuffers();
-
-        // Ensures atomicity among the public methods
-        mutable     Mutex                       mLock;
-
-        // mSurfaceLock synchronizes access to mSurface between
-        // setPreviewSurface() and postPreviewFrame().  Note that among
-        // the public methods, all accesses to mSurface are
-        // syncrhonized by mLock.  However, postPreviewFrame() is called
-        // by the CameraHardwareInterface callback, and needs to
-        // access mSurface.  It cannot hold mLock, however, because
-        // stopPreview() may be holding that lock while attempting
-        // to stop preview, and stopPreview itself will block waiting
-        // for a callback from CameraHardwareInterface.  If this
-        // happens, it will cause a deadlock.
-        mutable     Mutex                       mSurfaceLock;
-        mutable     Condition                   mReady;
-                    sp<CameraService>           mCameraService;
-                    sp<ISurface>                mSurface;
-                    int                         mPreviewCallbackFlag;
-                    int                         mOrientation;
-
-                    sp<MediaPlayer>             mMediaPlayerClick;
-                    sp<MediaPlayer>             mMediaPlayerBeep;
-
-                    // these are immutable once the object is created,
-                    // they don't need to be protected by a lock
-                    sp<ICameraClient>           mCameraClient;
-                    sp<CameraHardwareInterface> mHardware;
-                    pid_t                       mClientPid;
-                    bool                        mUseOverlay;
-
-                    sp<OverlayRef>              mOverlayRef;
-                    int                         mOverlayW;
-                    int                         mOverlayH;
-
-        mutable     Mutex                       mPreviewLock;
-                    sp<MemoryHeapBase>          mPreviewBuffer;
-    };
-
-// ----------------------------------------------------------------------------
-
-                            CameraService();
-    virtual                 ~CameraService();
-
-    // We use a count for number of clients (shoule only be 0 or 1).
-    volatile    int32_t                     mUsers;
-    virtual     void                        incUsers();
-    virtual     void                        decUsers();
-
-    mutable     Mutex                       mServiceLock;
-                wp<Client>                  mClient;
-
-#if DEBUG_HEAP_LEAKS
-                wp<IMemoryHeap>             gWeakHeap;
-#endif
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif
diff --git a/camera/libcameraservice/CannedJpeg.h b/camera/libcameraservice/CannedJpeg.h
deleted file mode 100644
index b6266fb..0000000
--- a/camera/libcameraservice/CannedJpeg.h
+++ /dev/null
@@ -1,734 +0,0 @@
-const int kCannedJpegWidth = 320;
-const int kCannedJpegHeight = 240;
-const int kCannedJpegSize = 8733;
-
-const char kCannedJpeg[] = {
-  0xff,  0xd8,  0xff,  0xe0,  0x00,  0x10,  0x4a,  0x46,  0x49,  0x46,  0x00,  0x01,
-  0x01,  0x01,  0x00,  0x60,  0x00,  0x60,  0x00,  0x00,  0xff,  0xe1,  0x00,  0x66,
-  0x45,  0x78,  0x69,  0x66,  0x00,  0x00,  0x49,  0x49,  0x2a,  0x00,  0x08,  0x00,
-  0x00,  0x00,  0x04,  0x00,  0x1a,  0x01,  0x05,  0x00,  0x01,  0x00,  0x00,  0x00,
-  0x3e,  0x00,  0x00,  0x00,  0x1b,  0x01,  0x05,  0x00,  0x01,  0x00,  0x00,  0x00,
-  0x46,  0x00,  0x00,  0x00,  0x28,  0x01,  0x03,  0x00,  0x01,  0x00,  0x00,  0x00,
-  0x02,  0x00,  0x00,  0x00,  0x31,  0x01,  0x02,  0x00,  0x10,  0x00,  0x00,  0x00,
-  0x4e,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x00,  0x60,  0x00,  0x00,  0x00,
-  0x01,  0x00,  0x00,  0x00,  0x60,  0x00,  0x00,  0x00,  0x01,  0x00,  0x00,  0x00,
-  0x50,  0x61,  0x69,  0x6e,  0x74,  0x2e,  0x4e,  0x45,  0x54,  0x20,  0x76,  0x33,
-  0x2e,  0x33,  0x36,  0x00,  0xff,  0xdb,  0x00,  0x43,  0x00,  0x03,  0x02,  0x02,
-  0x03,  0x02,  0x02,  0x03,  0x03,  0x03,  0x03,  0x04,  0x03,  0x03,  0x04,  0x05,
-  0x08,  0x05,  0x05,  0x04,  0x04,  0x05,  0x0a,  0x07,  0x07,  0x06,  0x08,  0x0c,
-  0x0a,  0x0c,  0x0c,  0x0b,  0x0a,  0x0b,  0x0b,  0x0d,  0x0e,  0x12,  0x10,  0x0d,
-  0x0e,  0x11,  0x0e,  0x0b,  0x0b,  0x10,  0x16,  0x10,  0x11,  0x13,  0x14,  0x15,
-  0x15,  0x15,  0x0c,  0x0f,  0x17,  0x18,  0x16,  0x14,  0x18,  0x12,  0x14,  0x15,
-  0x14,  0xff,  0xdb,  0x00,  0x43,  0x01,  0x03,  0x04,  0x04,  0x05,  0x04,  0x05,
-  0x09,  0x05,  0x05,  0x09,  0x14,  0x0d,  0x0b,  0x0d,  0x14,  0x14,  0x14,  0x14,
-  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,
-  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,
-  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,
-  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0x14,  0xff,  0xc0,
-  0x00,  0x11,  0x08,  0x00,  0xf0,  0x01,  0x40,  0x03,  0x01,  0x22,  0x00,  0x02,
-  0x11,  0x01,  0x03,  0x11,  0x01,  0xff,  0xc4,  0x00,  0x1f,  0x00,  0x00,  0x01,
-  0x05,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x00,  0x00,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,  0x08,  0x09,
-  0x0a,  0x0b,  0xff,  0xc4,  0x00,  0xb5,  0x10,  0x00,  0x02,  0x01,  0x03,  0x03,
-  0x02,  0x04,  0x03,  0x05,  0x05,  0x04,  0x04,  0x00,  0x00,  0x01,  0x7d,  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,  0xff,  0xc4,  0x00,  0x1f,  0x01,  0x00,  0x03,
-  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x01,  0x00,  0x00,  0x00,
-  0x00,  0x00,  0x00,  0x01,  0x02,  0x03,  0x04,  0x05,  0x06,  0x07,  0x08,  0x09,
-  0x0a,  0x0b,  0xff,  0xc4,  0x00,  0xb5,  0x11,  0x00,  0x02,  0x01,  0x02,  0x04,
-  0x04,  0x03,  0x04,  0x07,  0x05,  0x04,  0x04,  0x00,  0x01,  0x02,  0x77,  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,  0xff,  0xda,  0x00,  0x0c,  0x03,  0x01,  0x00,
-  0x02,  0x11,  0x03,  0x11,  0x00,  0x3f,  0x00,  0xf9,  0xd2,  0xa3,  0x95,  0xbb,
-  0x54,  0x84,  0xe0,  0x66,  0xa0,  0x27,  0x27,  0x35,  0xed,  0x9e,  0x50,  0x95,
-  0x2c,  0x4b,  0xc6,  0x6a,  0x35,  0x1b,  0x8e,  0x2a,  0x70,  0x30,  0x28,  0x00,
-  0xa8,  0xe5,  0x6e,  0x71,  0x52,  0x31,  0xda,  0x33,  0x50,  0x13,  0x93,  0x40,
-  0x09,  0x52,  0xc6,  0xb8,  0x19,  0xf5,  0xa6,  0x2a,  0xee,  0x6c,  0x54,  0xd4,
-  0x00,  0x54,  0x52,  0x36,  0x5b,  0x1e,  0x95,  0x23,  0xb6,  0xd5,  0xcd,  0x41,
-  0x40,  0x05,  0x4c,  0x8b,  0xb5,  0x7d,  0xea,  0x34,  0x5d,  0xcd,  0xed,  0x53,
-  0x50,  0x01,  0x50,  0xbb,  0x6e,  0x6f,  0x6a,  0x91,  0xdb,  0x6a,  0xfb,  0xd4,
-  0x34,  0x00,  0x54,  0xe8,  0xbb,  0x57,  0x15,  0x1c,  0x6b,  0x96,  0xcf,  0xa5,
-  0x4b,  0x40,  0x05,  0x42,  0xcd,  0xb9,  0xb3,  0x4f,  0x91,  0xb0,  0x31,  0xeb,
-  0x51,  0x50,  0x02,  0x81,  0x93,  0x53,  0xa8,  0xda,  0x31,  0x51,  0xc4,  0xbc,
-  0xe6,  0xa4,  0xa0,  0x00,  0x9c,  0x0a,  0x81,  0x8e,  0xe3,  0x9a,  0x92,  0x56,
-  0xe3,  0x15,  0x15,  0x00,  0x28,  0x19,  0x38,  0xa9,  0xc0,  0xc0,  0xc5,  0x47,
-  0x12,  0xf7,  0xa9,  0x28,  0x00,  0x27,  0x00,  0x9a,  0x80,  0x9c,  0x9c,  0xd3,
-  0xe5,  0x6e,  0xd5,  0x1d,  0x00,  0x2a,  0x8d,  0xc7,  0x15,  0x3d,  0x32,  0x35,
-  0xc0,  0xcf,  0xad,  0x3e,  0x80,  0x11,  0x8e,  0xd1,  0x9a,  0x82,  0x9f,  0x23,
-  0x64,  0xe3,  0xd2,  0x99,  0x40,  0x0e,  0x45,  0xdc,  0xde,  0xd5,  0x35,  0x36,
-  0x35,  0xc2,  0xfb,  0x9a,  0x75,  0x00,  0x35,  0xdb,  0x6a,  0xfb,  0xd4,  0x34,
-  0xe9,  0x1b,  0x73,  0x7b,  0x0a,  0x6d,  0x00,  0x3e,  0x35,  0xcb,  0x7b,  0x0a,
-  0x96,  0x91,  0x17,  0x6a,  0xd2,  0xd0,  0x03,  0x64,  0x6c,  0x2f,  0xb9,  0xa8,
-  0x69,  0xce,  0xdb,  0x9a,  0x9b,  0xd6,  0x80,  0x1f,  0x12,  0xe4,  0xe7,  0xd2,
-  0xa5,  0xa4,  0x51,  0xb4,  0x62,  0x97,  0xa5,  0x00,  0x67,  0xc9,  0xad,  0xd8,
-  0x91,  0x81,  0x72,  0x9f,  0x9d,  0x47,  0xfd,  0xb3,  0x65,  0xff,  0x00,  0x3f,
-  0x29,  0x5f,  0xa0,  0x1f,  0xf0,  0xe9,  0x6f,  0x09,  0x7f,  0xd0,  0xfb,  0xad,
-  0x7f,  0xe0,  0x24,  0x34,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,
-  0xee,  0xb5,  0xff,  0x00,  0x80,  0x90,  0xd7,  0x3f,  0xb7,  0x87,  0x73,  0x6f,
-  0x63,  0x33,  0xe0,  0x28,  0xf5,  0x9b,  0x11,  0xc9,  0xb9,  0x4c,  0xfd,  0x69,
-  0xff,  0x00,  0xdb,  0x96,  0x1f,  0xf3,  0xf5,  0x1f,  0xe7,  0x5f,  0x7d,  0x7f,
-  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,  0x00,  0x80,
-  0x90,  0xd1,  0xff,  0x00,  0x0e,  0x96,  0xf0,  0x97,  0xfd,  0x0f,  0xba,  0xd7,
-  0xfe,  0x02,  0x43,  0x47,  0xb7,  0x87,  0x70,  0xf6,  0x33,  0x3e,  0x02,  0x93,
-  0x5b,  0xb1,  0x3c,  0x0b,  0x94,  0xc7,  0xd6,  0x99,  0xfd,  0xb3,  0x65,  0xff,
-  0x00,  0x3f,  0x29,  0xf9,  0xd7,  0xe8,  0x07,  0xfc,  0x3a,  0x5b,  0xc2,  0x5f,
-  0xf4,  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1f,  0xf0,  0xe9,  0x6f,  0x09,
-  0x7f,  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0xbd,  0xbc,  0x03,  0xd8,
-  0xcc,  0xf8,  0x0e,  0x3d,  0x6a,  0xc1,  0x47,  0x37,  0x29,  0x9f,  0xad,  0x3b,
-  0xfb,  0x72,  0xc3,  0xfe,  0x7e,  0xa3,  0xfc,  0xeb,  0xef,  0xaf,  0xf8,  0x74,
-  0xb7,  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,  0x1a,  0x3f,  0xe1,
-  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,  0xc0,  0x48,
-  0x69,  0xfb,  0x78,  0x77,  0x0f,  0x63,  0x33,  0xe0,  0x19,  0x35,  0xbb,  0x26,
-  0x3c,  0x5c,  0xa6,  0x3e,  0xb4,  0xdf,  0xed,  0x9b,  0x2f,  0xf9,  0xf9,  0x4a,
-  0xfd,  0x00,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,  0x6b,
-  0xff,  0x00,  0x01,  0x21,  0xa3,  0xfe,  0x1d,  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,
-  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x97,  0xb7,  0x80,  0x7b,  0x19,  0x9f,  0x01,
-  0xa6,  0xb5,  0x60,  0xab,  0xff,  0x00,  0x1f,  0x51,  0xe7,  0xeb,  0x4e,  0xfe,
-  0xdc,  0xb0,  0xff,  0x00,  0x9f,  0xa8,  0xff,  0x00,  0x3a,  0xfb,  0xeb,  0xfe,
-  0x1d,  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x8f,
-  0xf8,  0x74,  0xb7,  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,  0x1a,
-  0x3d,  0xbc,  0x03,  0xd8,  0xcc,  0xf8,  0x05,  0xf5,  0xab,  0x26,  0x6f,  0xf8,
-  0xf9,  0x4c,  0x7d,  0x69,  0xbf,  0xdb,  0x36,  0x5f,  0xf3,  0xf2,  0x9f,  0x9d,
-  0x7e,  0x80,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,
-  0xff,  0x00,  0x80,  0x90,  0xd1,  0xff,  0x00,  0x0e,  0x96,  0xf0,  0x97,  0xfd,
-  0x0f,  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xb7,  0x80,  0x7b,  0x19,  0x9f,
-  0x02,  0x26,  0xb5,  0x60,  0xab,  0x8f,  0xb5,  0x47,  0xf9,  0xd2,  0xff,  0x00,
-  0x6e,  0x58,  0x7f,  0xcf,  0xd4,  0x7f,  0x9d,  0x7d,  0xf5,  0xff,  0x00,  0x0e,
-  0x96,  0xf0,  0x97,  0xfd,  0x0f,  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xfc,
-  0x3a,  0x5b,  0xc2,  0x5f,  0xf4,  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1e,
-  0xde,  0x01,  0xec,  0x66,  0x7c,  0x00,  0xda,  0xd5,  0x93,  0x1c,  0xfd,  0xa5,
-  0x3f,  0x3a,  0x4f,  0xed,  0x8b,  0x2f,  0xf9,  0xf9,  0x4f,  0xce,  0xbf,  0x40,
-  0x3f,  0xe1,  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,
-  0xc0,  0x48,  0x68,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,
-  0x6b,  0xff,  0x00,  0x01,  0x21,  0xa7,  0xed,  0xe1,  0xdc,  0x3d,  0x8c,  0xcf,
-  0x81,  0x57,  0x5a,  0xb0,  0x51,  0x8f,  0xb5,  0x47,  0xf9,  0xd1,  0xfd,  0xb9,
-  0x61,  0xff,  0x00,  0x3f,  0x49,  0xf9,  0xd7,  0xdf,  0x5f,  0xf0,  0xe9,  0x6f,
-  0x09,  0x7f,  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0x7f,  0xc3,  0xa5,
-  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,  0x00,  0x80,  0x90,  0xd2,
-  0xf6,  0xf0,  0x0f,  0x63,  0x33,  0xe0,  0x06,  0xd6,  0xac,  0x98,  0xe7,  0xed,
-  0x29,  0xf9,  0xd2,  0x0d,  0x62,  0xcb,  0xfe,  0x7e,  0x53,  0xf3,  0xaf,  0xd0,
-  0x0f,  0xf8,  0x74,  0xb7,  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,
-  0x1a,  0x3f,  0xe1,  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,
-  0x00,  0xc0,  0x48,  0x69,  0xfb,  0x78,  0x77,  0x0f,  0x63,  0x33,  0xe0,  0x51,
-  0xad,  0xd8,  0x01,  0x8f,  0xb5,  0x47,  0xf9,  0xd0,  0x75,  0xcb,  0x0c,  0x7f,
-  0xc7,  0xca,  0x7e,  0x75,  0xf7,  0xd7,  0xfc,  0x3a,  0x5b,  0xc2,  0x5f,  0xf4,
-  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1f,  0xf0,  0xe9,  0x6f,  0x09,  0x7f,
-  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0x7b,  0x78,  0x77,  0x0f,  0x63,
-  0x33,  0xf3,  0xfc,  0xeb,  0x36,  0x44,  0xff,  0x00,  0xc7,  0xca,  0x7e,  0x74,
-  0xa3,  0x58,  0xb1,  0x24,  0x66,  0xe5,  0x31,  0xf5,  0xaf,  0xbf,  0xff,  0x00,
-  0xe1,  0xd2,  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,  0xc0,
-  0x48,  0x68,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,  0x6b,
-  0xff,  0x00,  0x01,  0x21,  0xa3,  0xdb,  0xc3,  0xb8,  0x7b,  0x19,  0x9f,  0x02,
-  0xff,  0x00,  0x6d,  0xd8,  0x7f,  0xcf,  0xd4,  0x7f,  0x9d,  0x07,  0x5c,  0xb1,
-  0x03,  0x8b,  0x94,  0xcf,  0xd6,  0xbe,  0xfa,  0xff,  0x00,  0x87,  0x4b,  0x78,
-  0x4b,  0xfe,  0x87,  0xdd,  0x6b,  0xff,  0x00,  0x01,  0x21,  0xa3,  0xfe,  0x1d,
-  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x8f,  0x6f,
-  0x0e,  0xe1,  0xec,  0x66,  0x7e,  0x7f,  0xff,  0x00,  0x6c,  0xd9,  0x7f,  0xcf,
-  0xca,  0x7e,  0x74,  0xab,  0xac,  0x58,  0xe7,  0x9b,  0x94,  0xc7,  0xd6,  0xbe,
-  0xff,  0x00,  0xff,  0x00,  0x87,  0x4b,  0x78,  0x4b,  0xfe,  0x87,  0xdd,  0x6b,
-  0xff,  0x00,  0x01,  0x21,  0xa3,  0xfe,  0x1d,  0x2d,  0xe1,  0x2f,  0xfa,  0x1f,
-  0x75,  0xaf,  0xfc,  0x04,  0x86,  0x8f,  0x6f,  0x0e,  0xe1,  0xec,  0x66,  0x7c,
-  0x0b,  0xfd,  0xb9,  0x61,  0xff,  0x00,  0x3f,  0x51,  0xfe,  0x74,  0x8d,  0xae,
-  0x58,  0xed,  0x38,  0xb9,  0x4c,  0xfd,  0x6b,  0xef,  0xbf,  0xf8,  0x74,  0xb7,
-  0x84,  0xbf,  0xe8,  0x7d,  0xd6,  0xbf,  0xf0,  0x12,  0x1a,  0x3f,  0xe1,  0xd2,
-  0xde,  0x12,  0xff,  0x00,  0xa1,  0xf7,  0x5a,  0xff,  0x00,  0xc0,  0x48,  0x68,
-  0xf6,  0xf0,  0xee,  0x1e,  0xc6,  0x67,  0xe7,  0xff,  0x00,  0xf6,  0xc5,  0x97,
-  0xfc,  0xfc,  0xa7,  0xe7,  0x4e,  0x4d,  0x62,  0xc7,  0x77,  0x37,  0x29,  0xf9,
-  0xd7,  0xdf,  0xdf,  0xf0,  0xe9,  0x6f,  0x09,  0x7f,  0xd0,  0xfb,  0xad,  0x7f,
-  0xe0,  0x24,  0x34,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,
-  0xb5,  0xff,  0x00,  0x80,  0x90,  0xd1,  0xed,  0xe1,  0xdc,  0x3d,  0x8c,  0xcf,
-  0x81,  0x7f,  0xb7,  0x2c,  0x3f,  0xe7,  0xea,  0x3f,  0xce,  0x91,  0xf5,  0xcb,
-  0x1c,  0x71,  0x72,  0x9f,  0x9d,  0x7d,  0xf7,  0xff,  0x00,  0x0e,  0x96,  0xf0,
-  0x97,  0xfd,  0x0f,  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xfc,  0x3a,  0x5b,
-  0xc2,  0x5f,  0xf4,  0x3e,  0xeb,  0x5f,  0xf8,  0x09,  0x0d,  0x1e,  0xde,  0x1d,
-  0xc3,  0xd8,  0xcc,  0xfc,  0xff,  0x00,  0xfe,  0xd9,  0xb2,  0xff,  0x00,  0x9f,
-  0x94,  0xfc,  0xe9,  0xd1,  0xeb,  0x36,  0x20,  0xe4,  0xdc,  0xa7,  0xe7,  0x5f,
-  0x7f,  0x7f,  0xc3,  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,
-  0x00,  0x80,  0x90,  0xd1,  0xff,  0x00,  0x0e,  0x96,  0xf0,  0x97,  0xfd,  0x0f,
-  0xba,  0xd7,  0xfe,  0x02,  0x43,  0x47,  0xb7,  0x87,  0x70,  0xf6,  0x33,  0x3e,
-  0x05,  0xfe,  0xdc,  0xb0,  0xff,  0x00,  0x9f,  0xa8,  0xff,  0x00,  0x3a,  0x6c,
-  0x9a,  0xdd,  0x89,  0x18,  0x17,  0x29,  0xf9,  0xd7,  0xdf,  0x9f,  0xf0,  0xe9,
-  0x6f,  0x09,  0x7f,  0xd0,  0xfb,  0xad,  0x7f,  0xe0,  0x24,  0x34,  0x7f,  0xc3,
-  0xa5,  0xbc,  0x25,  0xff,  0x00,  0x43,  0xee,  0xb5,  0xff,  0x00,  0x80,  0x90,
-  0xd1,  0xed,  0xe1,  0xdc,  0x3d,  0x8c,  0xcf,  0xbc,  0xa8,  0xa2,  0x8a,  0xf3,
-  0x0e,  0xf0,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,
-  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,
-  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0xa0,  0xbb,  0xbd,  0xb7,  0xb0,
-  0x88,  0x49,  0x73,  0x3c,  0x56,  0xf1,  0x96,  0x0a,  0x1e,  0x57,  0x0a,  0x09,
-  0x3d,  0x06,  0x4f,  0x7a,  0x9e,  0x95,  0xd3,  0x76,  0xea,  0x01,  0x45,  0x14,
-  0x53,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x82,  0xda,  0xf6,  0xde,
-  0xf0,  0xca,  0x2d,  0xe7,  0x8a,  0x73,  0x13,  0x98,  0xe4,  0xf2,  0xdc,  0x36,
-  0xc6,  0x1d,  0x54,  0xe3,  0xa1,  0xf6,  0xa4,  0xda,  0x4e,  0xcc,  0x09,  0xe8,
-  0xa2,  0x8a,  0x60,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,
-  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,
-  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x02,  0xb8,
-  0x51,  0x45,  0x14,  0x05,  0xc2,  0x8a,  0x28,  0xa0,  0x2e,  0x14,  0x51,  0x45,
-  0x01,  0x70,  0xa2,  0x8a,  0x28,  0x18,  0x51,  0x45,  0x14,  0x0a,  0xe1,  0x45,
-  0x14,  0x50,  0x17,  0x0a,  0x28,  0xa2,  0x80,  0xb9,  0xca,  0xfc,  0x4a,  0xf0,
-  0x52,  0x78,  0xef,  0xc2,  0xb7,  0x1a,  0x76,  0xef,  0x2e,  0xe5,  0x4f,  0x9d,
-  0x6c,  0xe4,  0xe0,  0x09,  0x00,  0x38,  0xcf,  0xb1,  0xc9,  0x1f,  0x8e,  0x7b,
-  0x57,  0x3d,  0xf0,  0x5b,  0xc7,  0x53,  0x6b,  0xba,  0x6c,  0xda,  0x16,  0xaa,
-  0x5a,  0x3d,  0x73,  0x4a,  0xfd,  0xd4,  0x8b,  0x2f,  0xdf,  0x91,  0x01,  0xc0,
-  0x27,  0xdc,  0x1e,  0x0f,  0xe0,  0x7b,  0xd7,  0xa3,  0x5c,  0xdc,  0xc5,  0x67,
-  0x04,  0x93,  0xcf,  0x2a,  0x43,  0x0c,  0x60,  0xb3,  0xc9,  0x23,  0x05,  0x55,
-  0x1e,  0xa4,  0x9e,  0x95,  0xf3,  0x47,  0xc4,  0x8f,  0x1f,  0xe9,  0x36,  0xdf,
-  0x10,  0xed,  0x3c,  0x41,  0xe1,  0x39,  0x99,  0xaf,  0xa1,  0xe2,  0xea,  0x42,
-  0x98,  0x82,  0x72,  0x38,  0xe3,  0x90,  0x4e,  0x46,  0x41,  0xe9,  0x9c,  0x0c,
-  0x7a,  0xd7,  0xc4,  0x67,  0x98,  0x9a,  0x59,  0x3e,  0x26,  0x9e,  0x64,  0xa6,
-  0x93,  0x7e,  0xec,  0xe3,  0x7d,  0x65,  0x1e,  0xe9,  0x77,  0x8b,  0xd7,  0xd3,
-  0x4b,  0x99,  0x4d,  0xa8,  0xbe,  0x63,  0xe9,  0xca,  0x2b,  0xe4,  0x3d,  0x73,
-  0xe3,  0x3f,  0x8b,  0xb5,  0xc6,  0x6d,  0xfa,  0xb4,  0x96,  0x71,  0x9e,  0x91,
-  0x59,  0x0f,  0x28,  0x0f,  0xc4,  0x7c,  0xdf,  0x99,  0xae,  0x56,  0xe7,  0x5a,
-  0xd4,  0x6f,  0x18,  0xb5,  0xc5,  0xfd,  0xd4,  0xec,  0x7b,  0xc9,  0x33,  0x31,
-  0xfd,  0x4d,  0x78,  0x75,  0xf8,  0xfb,  0x0b,  0x07,  0x6a,  0x14,  0x65,  0x25,
-  0xe6,  0xd2,  0xff,  0x00,  0x32,  0x1d,  0x75,  0xd1,  0x1f,  0x73,  0x51,  0x5f,
-  0x0b,  0xdb,  0xea,  0xf7,  0xf6,  0xad,  0xba,  0x0b,  0xdb,  0x88,  0x58,  0x77,
-  0x8e,  0x56,  0x53,  0xfa,  0x1a,  0xe9,  0xf4,  0x5f,  0x8b,  0xfe,  0x2e,  0xd0,
-  0xd9,  0x7c,  0xad,  0x66,  0x7b,  0x84,  0x1f,  0xf2,  0xce,  0xec,  0xf9,  0xc0,
-  0xff,  0x00,  0xdf,  0x59,  0x23,  0xf0,  0x34,  0xa8,  0x71,  0xf6,  0x1a,  0x4e,
-  0xd5,  0xa8,  0x4a,  0x2b,  0xc9,  0xa7,  0xfe,  0x40,  0xab,  0xae,  0xa8,  0xfa,
-  0x13,  0xe2,  0xff,  0x00,  0x8f,  0xcf,  0x82,  0xfc,  0x3e,  0x21,  0xb3,  0x6d,
-  0xda,  0xcd,  0xfe,  0x62,  0xb5,  0x45,  0xe5,  0x97,  0xb1,  0x7c,  0x7b,  0x67,
-  0x8f,  0x72,  0x3d,  0xea,  0x5f,  0x84,  0x7e,  0x05,  0x6f,  0x04,  0x78,  0x60,
-  0x2d,  0xd1,  0x2d,  0xa9,  0xde,  0xb0,  0x9e,  0xe8,  0x93,  0x9d,  0xad,  0x8e,
-  0x17,  0xf0,  0x1d,  0x4f,  0xa9,  0x35,  0xe2,  0x5e,  0x13,  0xf8,  0x89,  0x61,
-  0xac,  0xfc,  0x49,  0x8f,  0xc4,  0x3e,  0x30,  0x76,  0xcc,  0x68,  0x16,  0xd8,
-  0x43,  0x19,  0x68,  0x61,  0x61,  0xd0,  0x91,  0x92,  0x40,  0x1c,  0x9e,  0x33,
-  0xc9,  0xcd,  0x7d,  0x3b,  0x63,  0x7f,  0x6d,  0xaa,  0x5a,  0x45,  0x75,  0x69,
-  0x3c,  0x77,  0x36,  0xd2,  0x8d,  0xc9,  0x2c,  0x4c,  0x19,  0x58,  0x7b,  0x11,
-  0x5e,  0xde,  0x4d,  0x8b,  0xa3,  0x9d,  0xe3,  0x2a,  0x66,  0x1c,  0xe9,  0xf2,
-  0x5e,  0x30,  0x8f,  0x58,  0xae,  0xb2,  0x6b,  0xbc,  0xbf,  0x05,  0xa1,  0x50,
-  0x6a,  0x6f,  0x98,  0xb1,  0x45,  0x14,  0x57,  0xdc,  0x9b,  0x5c,  0x28,  0xa2,
-  0x8a,  0x02,  0xe1,  0x45,  0x14,  0x50,  0x17,  0x0a,  0x28,  0xa2,  0x80,  0xb8,
-  0x51,  0x45,  0x14,  0x05,  0xc2,  0x8a,  0x28,  0xa0,  0x2e,  0x14,  0x51,  0x45,
-  0x01,  0x70,  0xa2,  0x8a,  0x28,  0x0b,  0x8d,  0xcd,  0x19,  0xa6,  0xe4,  0x51,
-  0x91,  0x55,  0x62,  0x47,  0x66,  0x8c,  0xd3,  0x72,  0x28,  0xc8,  0xa2,  0xc0,
-  0x3b,  0x34,  0x66,  0x9b,  0x91,  0x46,  0x45,  0x16,  0x01,  0xd9,  0xa3,  0x34,
-  0xdc,  0x8a,  0x32,  0x28,  0xb0,  0x0e,  0xcd,  0x19,  0xa6,  0xe4,  0x52,  0xe4,
-  0x51,  0x60,  0xb8,  0xb9,  0xa3,  0x34,  0xdc,  0x8a,  0x32,  0x28,  0xb0,  0x0e,
-  0xdd,  0x46,  0x69,  0xb9,  0x14,  0x64,  0x51,  0x60,  0x1d,  0x9a,  0xa7,  0xac,
-  0x6b,  0x16,  0x9a,  0x0e,  0x9b,  0x71,  0xa8,  0x5f,  0x4c,  0x20,  0xb5,  0x81,
-  0x37,  0xbb,  0x9e,  0xc3,  0xd0,  0x7a,  0x93,  0xd0,  0x0a,  0xb5,  0x91,  0x5f,
-  0x39,  0xfe,  0xd1,  0x1e,  0x37,  0x7d,  0x4b,  0x5a,  0x4f,  0x0f,  0x5b,  0x48,
-  0x45,  0xa5,  0x96,  0x1e,  0x70,  0xa7,  0xef,  0xca,  0x46,  0x40,  0x3f,  0xee,
-  0x83,  0xf9,  0x93,  0xe9,  0x5e,  0x06,  0x79,  0x9a,  0xc3,  0x27,  0xc1,  0x4b,
-  0x12,  0xd5,  0xe5,  0xb4,  0x57,  0x76,  0xff,  0x00,  0xab,  0xbf,  0x24,  0x44,
-  0xe5,  0xca,  0xae,  0x72,  0xbf,  0x12,  0xbe,  0x2a,  0xea,  0x3e,  0x3e,  0xbd,
-  0x78,  0xd5,  0x9e,  0xd3,  0x48,  0x46,  0xfd,  0xd5,  0xa2,  0x9f,  0xbd,  0xe8,
-  0xcf,  0xea,  0x7f,  0x41,  0xdb,  0xd4,  0xc3,  0xe0,  0x5f,  0x85,  0x1a,  0xd7,
-  0x8f,  0xed,  0xe6,  0xb9,  0xb1,  0xf2,  0x2d,  0xed,  0x22,  0x6d,  0x86,  0x7b,
-  0x96,  0x21,  0x59,  0xb1,  0x9c,  0x0c,  0x02,  0x4f,  0x51,  0xf9,  0xd7,  0x19,
-  0x5e,  0xcd,  0xf0,  0x73,  0xe3,  0x16,  0x97,  0xe1,  0x0d,  0x06,  0x4d,  0x23,
-  0x57,  0x49,  0x63,  0x44,  0x95,  0xa5,  0x86,  0x78,  0x53,  0x78,  0x21,  0xba,
-  0xab,  0x0e,  0xb9,  0xcf,  0x7f,  0x7f,  0x6a,  0xfc,  0x1b,  0x2e,  0xa9,  0x87,
-  0xcd,  0xb3,  0x2f,  0x69,  0x9c,  0xd5,  0x6a,  0x2e,  0xfa,  0xde,  0xda,  0xf4,
-  0x57,  0xe8,  0xbf,  0xe1,  0x8e,  0x48,  0xda,  0x52,  0xf7,  0x8f,  0x30,  0xf1,
-  0x57,  0x85,  0x75,  0x0f,  0x06,  0xeb,  0x12,  0x69,  0xba,  0x94,  0x42,  0x3b,
-  0x84,  0x01,  0x83,  0x21,  0xca,  0xba,  0x9e,  0x8c,  0xa7,  0xb8,  0xac,  0x8a,
-  0xed,  0x3e,  0x2c,  0xf8,  0xee,  0x1f,  0x1f,  0xf8,  0x9c,  0x5e,  0xda,  0xc2,
-  0xf0,  0xda,  0x41,  0x08,  0x82,  0x2f,  0x33,  0x01,  0xd8,  0x02,  0x49,  0x63,
-  0xe9,  0xc9,  0x3c,  0x57,  0x17,  0x5e,  0x26,  0x3e,  0x9e,  0x1e,  0x96,  0x2a,
-  0xa4,  0x30,  0xb2,  0xe6,  0xa6,  0x9b,  0xb3,  0xee,  0x88,  0x76,  0xbe,  0x81,
-  0x5a,  0x1a,  0x06,  0x83,  0x7b,  0xe2,  0x7d,  0x5e,  0xdf,  0x4d,  0xd3,  0xe2,
-  0xf3,  0xae,  0xa7,  0x38,  0x55,  0xce,  0x00,  0x00,  0x64,  0x92,  0x7b,  0x00,
-  0x39,  0xac,  0xfa,  0xea,  0x3e,  0x1b,  0x78,  0xc1,  0x7c,  0x0d,  0xe2,  0xcb,
-  0x5d,  0x52,  0x58,  0x4c,  0xf6,  0xe1,  0x5a,  0x39,  0x51,  0x3e,  0xf6,  0xd6,
-  0x18,  0x24,  0x7b,  0x8e,  0x0d,  0x67,  0x83,  0x85,  0x1a,  0x98,  0x8a,  0x70,
-  0xc4,  0x4b,  0x96,  0x0d,  0xae,  0x67,  0xd9,  0x5f,  0x50,  0x56,  0xbe,  0xa6,
-  0x97,  0x8d,  0x7e,  0x0e,  0xeb,  0xde,  0x06,  0xd3,  0x17,  0x50,  0xbb,  0x36,
-  0xf7,  0x56,  0x99,  0x0b,  0x24,  0x96,  0xae,  0x4f,  0x96,  0x4f,  0x4d,  0xc0,
-  0x81,  0xc1,  0x3c,  0x66,  0xa9,  0xfc,  0x3e,  0xf8,  0x93,  0xaa,  0x78,  0x03,
-  0x50,  0x0f,  0x6c,  0xe6,  0x7b,  0x07,  0x6f,  0xdf,  0xd9,  0x3b,  0x7c,  0x8e,
-  0x3d,  0x47,  0xa3,  0x7b,  0xfe,  0x79,  0xaf,  0x45,  0xf8,  0xad,  0xf1,  0xb3,
-  0x47,  0xf1,  0x27,  0x85,  0x26,  0xd2,  0x34,  0x84,  0x9a,  0x67,  0xbb,  0x2b,
-  0xe6,  0xcb,  0x34,  0x7b,  0x04,  0x6a,  0x18,  0x36,  0x07,  0xa9,  0xc8,  0x1e,
-  0xd5,  0xe1,  0x95,  0xf4,  0x39,  0xab,  0xc2,  0x65,  0x79,  0x84,  0x67,  0x93,
-  0x55,  0x6d,  0x24,  0x9d,  0xd3,  0xbd,  0x9f,  0x55,  0x7e,  0xaa,  0xd6,  0xbe,
-  0xfb,  0xd8,  0xb9,  0x5a,  0x32,  0xf7,  0x59,  0xf6,  0xef,  0x86,  0xbc,  0x49,
-  0x63,  0xe2,  0xbd,  0x1a,  0xdf,  0x53,  0xd3,  0xe5,  0xf3,  0x2d,  0xe6,  0x1d,
-  0xfe,  0xf2,  0x1e,  0xea,  0xc3,  0xb1,  0x15,  0xa9,  0x9a,  0xf9,  0x7b,  0xe0,
-  0x27,  0x8d,  0xe4,  0xf0,  0xef,  0x8a,  0x53,  0x4a,  0x9e,  0x43,  0xfd,  0x9f,
-  0xa9,  0x30,  0x8f,  0x69,  0x3c,  0x24,  0xdf,  0xc0,  0xc3,  0xeb,  0xf7,  0x7f,
-  0x11,  0xe9,  0x5f,  0x4f,  0xe4,  0x57,  0xee,  0x3c,  0x3f,  0x9b,  0xc7,  0x39,
-  0xc1,  0x2a,  0xed,  0x5a,  0x6b,  0x49,  0x2f,  0x3f,  0xf2,  0x7b,  0xfe,  0x1d,
-  0x0e,  0xb8,  0x4f,  0x99,  0x5c,  0x76,  0x4d,  0x19,  0xa6,  0xe4,  0x51,  0x91,
-  0x5f,  0x4b,  0x62,  0xc7,  0x64,  0xd1,  0x9a,  0x6e,  0x45,  0x19,  0x14,  0x58,
-  0x2e,  0x3b,  0x34,  0x66,  0x9b,  0x91,  0x46,  0x45,  0x16,  0x0b,  0x8e,  0xcd,
-  0x19,  0xa6,  0xe4,  0x51,  0x91,  0x45,  0x80,  0x76,  0x68,  0xcd,  0x37,  0x34,
-  0x64,  0x51,  0x60,  0xb8,  0xec,  0xd1,  0x9a,  0x6e,  0x45,  0x19,  0x14,  0x58,
-  0x07,  0x64,  0xd1,  0x9a,  0x6e,  0x45,  0x19,  0x14,  0x58,  0x06,  0x6e,  0xa3,
-  0x75,  0x37,  0x34,  0x66,  0xae,  0xc4,  0x5c,  0x76,  0xea,  0x37,  0x53,  0x73,
-  0x46,  0x68,  0xb0,  0x5c,  0x76,  0xea,  0x37,  0x53,  0x73,  0x46,  0x68,  0xb0,
-  0x5c,  0x76,  0xea,  0x37,  0x53,  0x72,  0x28,  0xcd,  0x16,  0x0b,  0x8e,  0xdd,
-  0x46,  0xea,  0x6e,  0x68,  0xcd,  0x16,  0x0b,  0x8e,  0xdd,  0x46,  0xea,  0x6e,
-  0x68,  0xcd,  0x16,  0x0b,  0x8e,  0xdd,  0x46,  0xea,  0xc4,  0xf1,  0x57,  0x8c,
-  0x34,  0xaf,  0x06,  0x69,  0xff,  0x00,  0x6b,  0xd5,  0x2e,  0x44,  0x28,  0xc7,
-  0x08,  0x8a,  0x37,  0x3c,  0x87,  0xd1,  0x47,  0x7f,  0xe5,  0x5c,  0x0d,  0x9f,
-  0xed,  0x1f,  0xe1,  0xcb,  0x8b,  0xc1,  0x14,  0xd6,  0x97,  0xf6,  0xb0,  0x93,
-  0x81,  0x3b,  0xa2,  0xb0,  0x1e,  0xe4,  0x06,  0x27,  0xf2,  0xcd,  0x78,  0xf8,
-  0xac,  0xdf,  0x2f,  0xc0,  0xd4,  0x54,  0x71,  0x35,  0xa3,  0x19,  0x3e,  0x8d,
-  0xfe,  0x7d,  0xbe,  0x64,  0xb9,  0x25,  0xb9,  0xeb,  0x05,  0xf6,  0x82,  0x4f,
-  0x41,  0x5f,  0x10,  0xeb,  0x7a,  0x93,  0xeb,  0x3a,  0xcd,  0xf5,  0xfc,  0x84,
-  0x97,  0xb9,  0x9d,  0xe6,  0x39,  0xff,  0x00,  0x69,  0x89,  0xfe,  0xb5,  0xf6,
-  0xad,  0x8e,  0xa1,  0x6b,  0xab,  0x58,  0xc5,  0x75,  0x69,  0x34,  0x77,  0x36,
-  0xb3,  0x2e,  0xe4,  0x91,  0x0e,  0x55,  0x85,  0x78,  0x5f,  0xfc,  0x2d,  0x5f,
-  0x87,  0x3f,  0xf4,  0x25,  0x27,  0xfe,  0x00,  0xdb,  0xff,  0x00,  0x8d,  0x7c,
-  0x67,  0x18,  0xe1,  0xa8,  0x63,  0x61,  0x87,  0x55,  0x31,  0x31,  0xa7,  0x1f,
-  0x79,  0xab,  0xdd,  0xf3,  0x7c,  0x3a,  0xab,  0x76,  0xfd,  0x4c,  0xea,  0x59,
-  0xdb,  0x53,  0xc4,  0x68,  0xaf,  0x6e,  0xff,  0x00,  0x85,  0xab,  0xf0,  0xe7,
-  0xfe,  0x84,  0xa4,  0xff,  0x00,  0xc0,  0x1b,  0x7f,  0xf1,  0xa3,  0xfe,  0x16,
-  0xaf,  0xc3,  0x9f,  0xfa,  0x12,  0x93,  0xff,  0x00,  0x00,  0x6d,  0xff,  0x00,
-  0xc6,  0xbf,  0x33,  0xfe,  0xc5,  0xc0,  0xff,  0x00,  0xd0,  0x7c,  0x3e,  0xe9,
-  0x7f,  0x91,  0x8f,  0x2a,  0xee,  0x78,  0x8d,  0x15,  0xed,  0xdf,  0xf0,  0xb5,
-  0x7e,  0x1c,  0xff,  0x00,  0xd0,  0x94,  0x9f,  0xf8,  0x03,  0x6f,  0xfe,  0x34,
-  0x7f,  0xc2,  0xd5,  0xf8,  0x73,  0xff,  0x00,  0x42,  0x52,  0x7f,  0xe0,  0x0d,
-  0xbf,  0xf8,  0xd1,  0xfd,  0x8b,  0x81,  0xff,  0x00,  0xa0,  0xf8,  0x7d,  0xd2,
-  0xff,  0x00,  0x20,  0xe5,  0x5d,  0xcf,  0x11,  0xa2,  0xbd,  0xbb,  0xfe,  0x16,
-  0xaf,  0xc3,  0x9f,  0xfa,  0x12,  0x93,  0xff,  0x00,  0x00,  0x6d,  0xff,  0x00,
-  0xc6,  0x8f,  0xf8,  0x5a,  0xbf,  0x0e,  0x7f,  0xe8,  0x4a,  0x4f,  0xfc,  0x01,
-  0xb7,  0xff,  0x00,  0x1a,  0x3f,  0xb1,  0x70,  0x3f,  0xf4,  0x1f,  0x0f,  0xba,
-  0x5f,  0xe4,  0x1c,  0xab,  0xb9,  0xe2,  0x34,  0x57,  0xb7,  0x7f,  0xc2,  0xd5,
-  0xf8,  0x73,  0xff,  0x00,  0x42,  0x52,  0x7f,  0xe0,  0x0d,  0xbf,  0xf8,  0xd1,
-  0xff,  0x00,  0x0b,  0x57,  0xe1,  0xcf,  0xfd,  0x09,  0x49,  0xff,  0x00,  0x80,
-  0x36,  0xff,  0x00,  0xe3,  0x47,  0xf6,  0x2e,  0x07,  0xfe,  0x83,  0xe1,  0xf7,
-  0x4b,  0xfc,  0x83,  0x95,  0x77,  0x3c,  0x52,  0x09,  0xde,  0xda,  0x78,  0xe6,
-  0x89,  0x8a,  0x49,  0x1b,  0x07,  0x56,  0x1d,  0x41,  0x07,  0x20,  0xd7,  0xdb,
-  0xfa,  0x5d,  0xf0,  0xd4,  0x74,  0xdb,  0x4b,  0xb0,  0x30,  0x27,  0x85,  0x25,
-  0x03,  0xfd,  0xe5,  0x07,  0xfa,  0xd7,  0x85,  0xff,  0x00,  0xc2,  0xd5,  0xf8,
-  0x73,  0xff,  0x00,  0x42,  0x52,  0x7f,  0xe0,  0x0d,  0xbf,  0xf8,  0xd7,  0xb6,
-  0x69,  0x1a,  0x95,  0xa5,  0xc7,  0x87,  0xec,  0xaf,  0xe1,  0x55,  0xb3,  0xb1,
-  0x7b,  0x54,  0x99,  0x11,  0xf0,  0x82,  0x28,  0xca,  0x02,  0x01,  0xec,  0x30,
-  0x3f,  0x0e,  0x2b,  0xf4,  0x7e,  0x0e,  0xc2,  0xd0,  0xc1,  0xce,  0xbc,  0x69,
-  0x62,  0x63,  0x51,  0x34,  0x9b,  0x4a,  0xfa,  0x5a,  0xfa,  0xeb,  0xea,  0x6d,
-  0x4e,  0xca,  0xfa,  0x9a,  0x5b,  0xa8,  0xdd,  0x5e,  0x57,  0xab,  0xfe,  0xd1,
-  0x3e,  0x1b,  0xd3,  0xaf,  0x1a,  0x0b,  0x68,  0x6e,  0xf5,  0x15,  0x53,  0x83,
-  0x34,  0x28,  0xaa,  0x87,  0xe9,  0xb8,  0x82,  0x7f,  0x2a,  0xeb,  0xbc,  0x1b,
-  0xf1,  0x07,  0x45,  0xf1,  0xcd,  0xbb,  0xbe,  0x99,  0x70,  0x7c,  0xe8,  0xc6,
-  0x64,  0xb6,  0x98,  0x6d,  0x91,  0x07,  0xa9,  0x1d,  0xc7,  0xb8,  0xc8,  0xaf,
-  0xb7,  0xc3,  0xe7,  0x19,  0x76,  0x2a,  0xb7,  0xd5,  0xe8,  0x56,  0x8c,  0xa7,
-  0xd9,  0x3f,  0xcb,  0xbf,  0xc8,  0xd1,  0x49,  0x3d,  0x2e,  0x74,  0xdb,  0xa8,
-  0xcd,  0x37,  0x34,  0x64,  0x57,  0xb2,  0x55,  0xc7,  0x6e,  0xa3,  0x75,  0x37,
-  0x34,  0x66,  0x8b,  0x05,  0xc7,  0x6e,  0xa3,  0x75,  0x37,  0x34,  0x66,  0x8b,
-  0x05,  0xc7,  0x6e,  0xa3,  0x75,  0x37,  0x34,  0x66,  0x8b,  0x05,  0xc7,  0x6e,
-  0xa3,  0x75,  0x37,  0x34,  0x64,  0x51,  0x60,  0xb8,  0xed,  0xd4,  0x6e,  0xa6,
-  0xe4,  0x51,  0x9a,  0x2c,  0x17,  0x1b,  0x9a,  0x33,  0x51,  0xee,  0xa3,  0x75,
-  0x55,  0x88,  0xb9,  0x26,  0x68,  0xcd,  0x47,  0xba,  0x8d,  0xd4,  0x58,  0x2e,
-  0x49,  0x9a,  0x33,  0x51,  0xee,  0xa3,  0x75,  0x16,  0x15,  0xc9,  0x32,  0x28,
-  0xa8,  0xf7,  0x51,  0xba,  0x8b,  0x0e,  0xe4,  0x99,  0xa3,  0x35,  0x1e,  0xea,
-  0x37,  0x51,  0x60,  0xb9,  0x26,  0x68,  0xcd,  0x47,  0xba,  0x8c,  0xd3,  0xb0,
-  0x5c,  0xf9,  0x7b,  0xe3,  0xb6,  0xaf,  0x3e,  0xa5,  0xf1,  0x0e,  0xf2,  0xde,
-  0x47,  0x26,  0x1b,  0x24,  0x48,  0x62,  0x4e,  0xc0,  0x15,  0x0c,  0x4f,  0xe2,
-  0x58,  0xfe,  0x95,  0xe7,  0x95,  0xda,  0x7c,  0x64,  0xff,  0x00,  0x92,  0x97,
-  0xad,  0xff,  0x00,  0xbf,  0x1f,  0xfe,  0x8a,  0x4a,  0xe2,  0xeb,  0xf9,  0x47,
-  0x3a,  0x9c,  0xaa,  0x66,  0x78,  0x99,  0x49,  0xdd,  0xf3,  0xcb,  0xf0,  0x6d,
-  0x23,  0x92,  0x5b,  0x9e,  0xf7,  0xfb,  0x34,  0xeb,  0x13,  0xcd,  0x67,  0xac,
-  0xe9,  0xb2,  0x39,  0x6b,  0x78,  0x1a,  0x39,  0xa2,  0x04,  0xfd,  0xd2,  0xdb,
-  0x83,  0x0f,  0xc7,  0x68,  0xfd,  0x6b,  0xc1,  0x2b,  0xda,  0xff,  0x00,  0x66,
-  0x73,  0x8b,  0xed,  0x7f,  0xfe,  0xb9,  0xc3,  0xfc,  0xde,  0xbc,  0x52,  0xbd,
-  0x8c,  0xd2,  0x72,  0x9e,  0x4b,  0x97,  0x39,  0x3b,  0xdb,  0xda,  0xaf,  0x92,
-  0x92,  0xb1,  0x4f,  0xe1,  0x41,  0x45,  0x14,  0x57,  0xc6,  0x90,  0x14,  0x51,
-  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x14,  0x51,  0x45,  0x00,  0x15,  0xef,
-  0x7f,  0x13,  0xf5,  0x89,  0xf4,  0xef,  0x82,  0xbe,  0x19,  0xb6,  0x81,  0xca,
-  0x0b,  0xc8,  0x2d,  0x62,  0x94,  0x83,  0xd5,  0x04,  0x3b,  0x88,  0xfc,  0x48,
-  0x15,  0xe0,  0x95,  0xed,  0x7f,  0x17,  0x0f,  0xfc,  0x5a,  0x5f,  0x05,  0xff,
-  0x00,  0xd7,  0x38,  0x3f,  0xf4,  0x45,  0x7d,  0x96,  0x47,  0x39,  0x43,  0x03,
-  0x98,  0x4a,  0x2e,  0xcf,  0x91,  0x7e,  0x32,  0xb3,  0xfc,  0x0a,  0x8e,  0xcc,
-  0xf1,  0x4a,  0xe9,  0xbe,  0x1a,  0x6a,  0xf3,  0xe8,  0xbe,  0x3a,  0xd1,  0x67,
-  0x81,  0xca,  0x99,  0x2e,  0x52,  0x07,  0x00,  0xfd,  0xe4,  0x76,  0x0a,  0xc0,
-  0xfe,  0x07,  0xf4,  0xae,  0x66,  0xb6,  0x3c,  0x1b,  0xff,  0x00,  0x23,  0x7e,
-  0x87,  0xff,  0x00,  0x5f,  0xd0,  0x7f,  0xe8,  0xc5,  0xaf,  0x9b,  0xc0,  0xce,
-  0x54,  0xf1,  0x54,  0xa7,  0x07,  0x66,  0xa4,  0xbf,  0x31,  0x2d,  0xcf,  0xb4,
-  0x33,  0x46,  0x6a,  0x3d,  0xd4,  0x6e,  0xaf,  0xeb,  0x9b,  0x1d,  0x57,  0x24,
-  0xcd,  0x19,  0xa8,  0xf7,  0x51,  0xba,  0x8b,  0x0e,  0xe4,  0x99,  0xa3,  0x35,
-  0x1e,  0xea,  0x37,  0x51,  0x60,  0xb9,  0x26,  0x68,  0xcd,  0x47,  0xba,  0x8d,
-  0xd4,  0x58,  0x2e,  0x49,  0x9a,  0x33,  0x51,  0xee,  0xa3,  0x75,  0x16,  0x15,
-  0xc9,  0x33,  0x46,  0x6a,  0x3d,  0xd4,  0x6e,  0xa2,  0xc3,  0xb8,  0xdd,  0xd4,
-  0x9b,  0xa9,  0xbb,  0xa8,  0xdd,  0x5a,  0x19,  0xdc,  0x7e,  0xea,  0x4d,  0xd4,
-  0xdd,  0xd4,  0x6e,  0xa0,  0x57,  0x1f,  0xba,  0x8d,  0xd4,  0xcd,  0xd4,  0x6e,
-  0xa0,  0x77,  0x1f,  0xba,  0x8d,  0xd4,  0xcd,  0xd4,  0x6e,  0xa4,  0x2b,  0x8f,
-  0xdd,  0x49,  0xba,  0x9b,  0xba,  0x8d,  0xd4,  0xc2,  0xe3,  0xb7,  0x52,  0xee,
-  0xa6,  0x6e,  0xa3,  0x75,  0x20,  0xb9,  0xf2,  0x9f,  0xc6,  0x3f,  0xf9,  0x29,
-  0x5a,  0xdf,  0xfb,  0xf1,  0xff,  0x00,  0xe8,  0xb4,  0xae,  0x32,  0xbb,  0x2f,
-  0x8c,  0x5c,  0xfc,  0x49,  0xd6,  0xff,  0x00,  0xdf,  0x8f,  0xff,  0x00,  0x45,
-  0xa5,  0x71,  0xb5,  0xfc,  0x99,  0x9c,  0x7f,  0xc8,  0xcb,  0x13,  0xfe,  0x39,
-  0xff,  0x00,  0xe9,  0x4c,  0xc1,  0xee,  0x7b,  0x57,  0xec,  0xd2,  0x71,  0x7d,
-  0xaf,  0x7f,  0xd7,  0x38,  0x7f,  0x9b,  0xd7,  0x8a,  0xd7,  0xb4,  0x7e,  0xcd,
-  0x67,  0x17,  0xda,  0xf7,  0xfd,  0x73,  0x87,  0xf9,  0xbd,  0x78,  0xbd,  0x7b,
-  0x19,  0x97,  0xfc,  0x89,  0x32,  0xef,  0xfb,  0x8b,  0xff,  0x00,  0xa5,  0x21,
-  0xbd,  0x90,  0x51,  0x45,  0x15,  0xf2,  0x02,  0x0a,  0x28,  0xa2,  0x80,  0x0a,
-  0x28,  0xa2,  0x80,  0x0a,  0x28,  0xa2,  0x80,  0x0a,  0xf6,  0xaf,  0x8b,  0x47,
-  0x3f,  0x09,  0x7c,  0x17,  0xff,  0x00,  0x5c,  0xe0,  0xff,  0x00,  0xd1,  0x15,
-  0xe2,  0xb5,  0xed,  0x1f,  0x16,  0x4f,  0xfc,  0x5a,  0x6f,  0x06,  0x7f,  0xd7,
-  0x38,  0x3f,  0xf4,  0x45,  0x7d,  0x7e,  0x4d,  0xff,  0x00,  0x22,  0xfc,  0xc3,
-  0xfc,  0x11,  0xff,  0x00,  0xd2,  0x90,  0xd6,  0xcc,  0xf1,  0x7a,  0xd8,  0xf0,
-  0x67,  0xfc,  0x8e,  0x1a,  0x17,  0xfd,  0x7f,  0xc1,  0xff,  0x00,  0xa3,  0x16,
-  0xb1,  0xeb,  0x63,  0xc1,  0xdf,  0xf2,  0x37,  0x68,  0x7f,  0xf5,  0xfd,  0x07,
-  0xfe,  0x8c,  0x5a,  0xf9,  0xbc,  0x27,  0xfb,  0xcd,  0x3f,  0xf1,  0x2f,  0xcc,
-  0x48,  0xfb,  0x2b,  0x75,  0x1b,  0xa9,  0x9b,  0xa8,  0xdd,  0x5f,  0xd8,  0x16,
-  0x37,  0xb8,  0xfd,  0xd4,  0x6e,  0xa6,  0x6e,  0xa3,  0x75,  0x20,  0xb8,  0xed,
-  0xd4,  0xbb,  0xa9,  0x9b,  0xa8,  0xdd,  0x4c,  0x2e,  0x3f,  0x75,  0x26,  0xea,
-  0x6e,  0xea,  0x37,  0x52,  0x0b,  0x8f,  0xdd,  0x49,  0xba,  0x9b,  0xba,  0x8d,
-  0xd4,  0xec,  0x3b,  0x8f,  0xdd,  0x49,  0xba,  0x9b,  0xba,  0x8d,  0xd4,  0x0a,
-  0xe4,  0x74,  0x53,  0x33,  0x4b,  0x93,  0x57,  0x63,  0x3b,  0x8e,  0xa2,  0x9b,
-  0x9a,  0x4c,  0xd1,  0x60,  0xb8,  0xfa,  0x29,  0x99,  0xa3,  0x34,  0x58,  0x2e,
-  0x3f,  0x34,  0x53,  0x33,  0x4b,  0x93,  0x45,  0x82,  0xe3,  0xa8,  0xcd,  0x33,
-  0x34,  0x66,  0x8b,  0x05,  0xc7,  0xd1,  0x4d,  0xc9,  0xa3,  0x26,  0x8b,  0x05,
-  0xcf,  0x96,  0x3e,  0x30,  0x7f,  0xc9,  0x48,  0xd6,  0xbf,  0xdf,  0x8f,  0xff,
-  0x00,  0x45,  0xa5,  0x71,  0xb5,  0xdd,  0xfc,  0x6c,  0xd3,  0xa6,  0xb1,  0xf8,
-  0x85,  0x7f,  0x2c,  0x8a,  0x44,  0x77,  0x4b,  0x1c,  0xd1,  0xb7,  0x66,  0x1b,
-  0x02,  0x9f,  0xd5,  0x4d,  0x70,  0x95,  0xfc,  0x97,  0x9d,  0x42,  0x50,  0xcc,
-  0xf1,  0x31,  0x92,  0xb7,  0xbf,  0x2f,  0xfd,  0x29,  0x90,  0x7b,  0x3f,  0xec,
-  0xdb,  0xff,  0x00,  0x1f,  0xba,  0xef,  0xfd,  0x73,  0x87,  0xf9,  0xbd,  0x78,
-  0xc5,  0x7b,  0x87,  0xec,  0xe3,  0xa7,  0x4d,  0x1c,  0x3a,  0xd5,  0xf3,  0x29,
-  0x58,  0x24,  0x31,  0xc2,  0x8d,  0xfd,  0xe2,  0x37,  0x16,  0xfc,  0xb2,  0x3f,
-  0x3a,  0xf0,  0xfa,  0xf6,  0x73,  0x58,  0x4a,  0x19,  0x26,  0x5b,  0xcc,  0xad,
-  0x7f,  0x6a,  0xff,  0x00,  0xf2,  0x64,  0x01,  0x45,  0x14,  0x57,  0xc6,  0x00,
-  0x51,  0x45,  0x14,  0x00,  0x51,  0x45,  0x14,  0x00,  0x51,  0x45,  0x14,  0x00,
-  0x57,  0xb3,  0xfc,  0x57,  0xff,  0x00,  0x92,  0x51,  0xe0,  0xdf,  0xfa,  0xe7,
-  0x07,  0xfe,  0x88,  0xaf,  0x18,  0xaf,  0x70,  0xf8,  0x9b,  0xa7,  0x4d,  0x79,
-  0xf0,  0x77,  0xc3,  0x37,  0x11,  0x29,  0x74,  0xb5,  0x8a,  0xd9,  0xe4,  0xc7,
-  0x65,  0x30,  0xed,  0xcf,  0xe6,  0x40,  0xfc,  0x6b,  0xec,  0xf2,  0x38,  0x4a,
-  0x78,  0x0c,  0xc1,  0x45,  0x5f,  0xdc,  0x5f,  0x84,  0xae,  0xc0,  0xf0,  0xfa,
-  0xd8,  0xf0,  0x6f,  0xfc,  0x8d,  0xfa,  0x1f,  0xfd,  0x7f,  0x41,  0xff,  0x00,
-  0xa3,  0x16,  0xb1,  0xeb,  0xa2,  0xf8,  0x79,  0xa7,  0x4d,  0xaa,  0x78,  0xdf,
-  0x45,  0x86,  0x15,  0x2c,  0xcb,  0x75,  0x1c,  0xad,  0x8e,  0xca,  0x8c,  0x18,
-  0x9f,  0xc8,  0x57,  0xcd,  0x60,  0x61,  0x29,  0xe2,  0xe9,  0x46,  0x2a,  0xed,
-  0xca,  0x3f,  0x9a,  0x03,  0xeb,  0x9c,  0xd1,  0x4c,  0xcd,  0x2e,  0x4d,  0x7f,
-  0x60,  0x58,  0xbb,  0x8e,  0xa2,  0x99,  0x9a,  0x33,  0x45,  0x82,  0xe3,  0xe8,
-  0xa6,  0x66,  0x8c,  0xd1,  0x60,  0xb8,  0xfa,  0x29,  0x99,  0xa5,  0xc9,  0xa2,
-  0xc1,  0x71,  0xd9,  0xa2,  0x9b,  0x93,  0x49,  0x9a,  0x2c,  0x17,  0x1f,  0x45,
-  0x33,  0x34,  0x66,  0x8b,  0x05,  0xc6,  0x6e,  0xa3,  0x75,  0x30,  0x90,  0x3a,
-  0x9c,  0x51,  0x9a,  0xd2,  0xc6,  0x57,  0x1f,  0xba,  0x8d,  0xd4,  0xda,  0x4c,
-  0xd1,  0x60,  0xb8,  0xfd,  0xd4,  0x6e,  0xa6,  0x02,  0x0f,  0x43,  0x9a,  0x37,
-  0x01,  0xdf,  0x14,  0x58,  0x2e,  0x3f,  0x75,  0x1b,  0xa9,  0xb4,  0x94,  0x58,
-  0x2e,  0x3f,  0x75,  0x1b,  0xa9,  0xb4,  0x80,  0x83,  0xd0,  0xe6,  0x8b,  0x05,
-  0xc7,  0xee,  0xa3,  0x75,  0x30,  0x90,  0x3a,  0x9c,  0x51,  0x9a,  0x2c,  0x17,
-  0x31,  0x3c,  0x5d,  0xe0,  0xcd,  0x2f,  0xc6,  0xb6,  0x2b,  0x6f,  0xa8,  0xc4,
-  0x4b,  0x26,  0x4c,  0x53,  0xc6,  0x71,  0x24,  0x64,  0xf5,  0xc1,  0xfe,  0x87,
-  0x8a,  0xe0,  0x6d,  0x3f,  0x67,  0x7d,  0x32,  0x2b,  0xb0,  0xf7,  0x1a,  0xad,
-  0xcc,  0xf6,  0xe0,  0xe7,  0xca,  0x58,  0xd5,  0x09,  0x1e,  0x85,  0xb2,  0x7f,
-  0x95,  0x7a,  0xd5,  0x25,  0x78,  0x38,  0xcc,  0x87,  0x2c,  0xcc,  0x2b,  0x2a,
-  0xf8,  0x9a,  0x2a,  0x52,  0xef,  0xaa,  0xfb,  0xec,  0xd5,  0xfe,  0x77,  0x0b,
-  0x95,  0xf4,  0xad,  0x32,  0xd3,  0x44,  0xb0,  0x86,  0xca,  0xc6,  0x05,  0xb7,
-  0xb6,  0x88,  0x61,  0x23,  0x4e,  0x83,  0xfc,  0x4f,  0xbd,  0x7c,  0x6b,  0x5f,
-  0x69,  0x57,  0xc5,  0xb5,  0xf9,  0x8f,  0x88,  0xb0,  0x8d,  0x38,  0xe0,  0xe1,
-  0x05,  0x64,  0xb9,  0xec,  0x97,  0xfd,  0xb8,  0x34,  0x14,  0x51,  0x45,  0x7e,
-  0x32,  0x30,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,  0x28,  0x00,  0xa2,  0x8a,
-  0x28,  0x00,  0xaf,  0xad,  0xfc,  0x2b,  0x04,  0x57,  0x9e,  0x06,  0xd1,  0xad,
-  0xe7,  0x8d,  0x66,  0x86,  0x4d,  0x3a,  0x04,  0x78,  0xdc,  0x65,  0x58,  0x18,
-  0xd7,  0x20,  0x8a,  0xf9,  0x22,  0xbe,  0xba,  0xf0,  0x67,  0xfc,  0x89,  0xfa,
-  0x17,  0xfd,  0x78,  0x41,  0xff,  0x00,  0xa2,  0xd6,  0xbf,  0x5c,  0xf0,  0xee,
-  0x2a,  0x58,  0x9c,  0x42,  0x7b,  0x72,  0xaf,  0xcc,  0x47,  0x05,  0xab,  0x7e,
-  0xcf,  0x7a,  0x4d,  0xdd,  0xdb,  0x4b,  0x65,  0xa8,  0x4f,  0x63,  0x13,  0x1c,
-  0xf9,  0x25,  0x04,  0x80,  0x7b,  0x02,  0x48,  0x3f,  0x9e,  0x6b,  0xaf,  0xf0,
-  0x57,  0xc3,  0xcd,  0x27,  0xc0,  0xd1,  0xb9,  0xb3,  0x47,  0x9a,  0xee,  0x41,
-  0xb6,  0x4b,  0xa9,  0xb0,  0x5c,  0x8f,  0x41,  0xe8,  0x3d,  0x87,  0xe3,  0x5d,
-  0x36,  0x69,  0x6b,  0xf5,  0x7c,  0x37,  0x0f,  0xe5,  0x78,  0x3a,  0xff,  0x00,
-  0x59,  0xa1,  0x41,  0x46,  0x7d,  0xf5,  0xd3,  0xd1,  0x6c,  0xbe,  0x49,  0x0a,
-  0xe3,  0xb7,  0x51,  0xba,  0x99,  0x9a,  0x03,  0x03,  0xde,  0xbd,  0xfb,  0x05,
-  0xc7,  0xee,  0xa3,  0x75,  0x30,  0x90,  0x06,  0x4f,  0x14,  0x51,  0x60,  0xb8,
-  0xfd,  0xd4,  0x6e,  0xa6,  0xd1,  0x45,  0x82,  0xe3,  0xb7,  0x51,  0xba,  0x98,
-  0x08,  0x3d,  0x0e,  0x68,  0x24,  0x0e,  0xf4,  0x58,  0x2e,  0x3f,  0x75,  0x1b,
-  0xa9,  0x94,  0xb4,  0x58,  0x2e,  0x3b,  0x75,  0x1b,  0xa9,  0x99,  0xa0,  0x10,
-  0x7a,  0x1a,  0x2c,  0x17,  0x31,  0x62,  0xbd,  0x91,  0x46,  0xf7,  0x90,  0x3e,
-  0xd3,  0xf7,  0x1b,  0xa9,  0xad,  0x58,  0xa5,  0x13,  0x46,  0xae,  0xbd,  0x08,
-  0xac,  0x3f,  0x38,  0xff,  0x00,  0x71,  0x3f,  0xef,  0x91,  0x56,  0x52,  0xf1,
-  0xe3,  0x48,  0x55,  0x42,  0x80,  0x7a,  0x80,  0x3d,  0xeb,  0xb2,  0x70,  0xbe,
-  0xc7,  0x9d,  0x4e,  0xaf,  0x2e,  0xec,  0xd6,  0xcd,  0x36,  0x59,  0x44,  0x31,
-  0xb3,  0xb7,  0x41,  0x49,  0xba,  0xb3,  0x1e,  0xf2,  0x49,  0x12,  0x65,  0x60,
-  0x08,  0x1d,  0x01,  0x1e,  0xf5,  0x84,  0x61,  0xcc,  0x75,  0x4e,  0xa7,  0x22,
-  0x1b,  0x2d,  0xec,  0x8c,  0x0b,  0xa4,  0x81,  0x37,  0x1f,  0xb8,  0xbd,  0x7e,
-  0xb4,  0xb1,  0x5e,  0xc8,  0xa0,  0x3b,  0xb8,  0x7d,  0xa7,  0xee,  0x37,  0x5f,
-  0xad,  0x57,  0xf3,  0x8f,  0xf7,  0x13,  0xfe,  0xf9,  0x14,  0x79,  0xc7,  0xfb,
-  0x89,  0xff,  0x00,  0x7c,  0x8a,  0xeb,  0xe5,  0x56,  0xb5,  0x8e,  0x0e,  0x77,
-  0x7b,  0xdc,  0xdd,  0x8e,  0x41,  0x2a,  0x2b,  0xaf,  0x42,  0x33,  0x4e,  0xac,
-  0xa8,  0xef,  0x1d,  0x3c,  0x85,  0x00,  0x05,  0x3d,  0x40,  0x1e,  0xe6,  0xb4,
-  0x77,  0x57,  0x24,  0xa3,  0xca,  0x77,  0xc2,  0x7c,  0xe8,  0x74,  0x92,  0x08,
-  0xd1,  0x99,  0x8f,  0x00,  0x66,  0xb2,  0xa5,  0xbd,  0x91,  0x81,  0x74,  0x70,
-  0x99,  0x38,  0xd8,  0x3a,  0xfd,  0x69,  0xd2,  0x5e,  0x3b,  0xf9,  0xea,  0x40,
-  0x2a,  0x3a,  0x02,  0x3d,  0xc5,  0x55,  0xf3,  0x8f,  0xf7,  0x13,  0xfe,  0xf9,
-  0x15,  0xbc,  0x21,  0x6d,  0xce,  0x6a,  0x95,  0x6f,  0xa2,  0x64,  0xf1,  0x5e,
-  0x48,  0xa3,  0x7b,  0x48,  0x1f,  0x69,  0xfb,  0x8d,  0xd4,  0xd6,  0xac,  0x52,
-  0x89,  0xa3,  0x57,  0x5e,  0x86,  0xb0,  0xfc,  0xe3,  0xfd,  0xc4,  0xff,  0x00,
-  0xbe,  0x45,  0x59,  0x4b,  0xc7,  0x8d,  0x61,  0x0a,  0x14,  0x03,  0xd4,  0x01,
-  0xef,  0x44,  0xe1,  0x7d,  0x85,  0x4e,  0xaf,  0x2e,  0xec,  0xd6,  0xcd,  0x15,
-  0x1e,  0xea,  0x5d,  0xd5,  0xcd,  0x63,  0xba,  0xe3,  0xeb,  0xc0,  0xbc,  0x71,
-  0xf0,  0x57,  0x55,  0x83,  0x57,  0x9e,  0xe7,  0x44,  0x85,  0x6f,  0x6c,  0xa6,
-  0x72,  0xe2,  0x25,  0x70,  0xaf,  0x16,  0x4e,  0x76,  0xe0,  0x91,  0x91,  0xe9,
-  0x8a,  0xf7,  0xad,  0xd4,  0x66,  0xbe,  0x7f,  0x39,  0xc8,  0xf0,  0x99,  0xe5,
-  0x18,  0xd2,  0xc4,  0xdd,  0x72,  0xbb,  0xa6,  0xb7,  0x5d,  0xfb,  0xef,  0xe8,
-  0x17,  0xb1,  0xf2,  0xc5,  0xff,  0x00,  0xc3,  0x5f,  0x12,  0xe9,  0x96,  0x53,
-  0x5d,  0xdd,  0x69,  0x52,  0x43,  0x6f,  0x0a,  0x97,  0x92,  0x42,  0xe8,  0x42,
-  0x81,  0xd4,  0xf0,  0x6b,  0x99,  0xaf,  0xaa,  0xfe,  0x21,  0x9c,  0xf8,  0x1f,
-  0x5c,  0xff,  0x00,  0xaf,  0x47,  0xfe,  0x55,  0xf2,  0xa5,  0x7e,  0x01,  0xc5,
-  0x59,  0x1e,  0x1f,  0x22,  0xc4,  0x53,  0xa3,  0x87,  0x93,  0x92,  0x94,  0x6f,
-  0xef,  0x5b,  0xbd,  0xba,  0x24,  0x5a,  0x77,  0x0a,  0xe9,  0xec,  0xbe,  0x19,
-  0xf8,  0x9b,  0x51,  0xb3,  0x86,  0xea,  0xdb,  0x49,  0x92,  0x5b,  0x79,  0x90,
-  0x49,  0x1b,  0x87,  0x40,  0x19,  0x48,  0xc8,  0x3d,  0x6b,  0x98,  0xaf,  0xac,
-  0x3c,  0x08,  0x71,  0xe0,  0xad,  0x0b,  0xfe,  0xbc,  0xa1,  0xff,  0x00,  0xd0,
-  0x05,  0x57,  0x0a,  0xe4,  0x58,  0x7c,  0xf6,  0xbd,  0x5a,  0x58,  0x89,  0x4a,
-  0x2a,  0x2a,  0xfe,  0xed,  0xbb,  0xdb,  0xaa,  0x60,  0xdd,  0x8f,  0x9e,  0xdb,
-  0xe1,  0x4f,  0x8a,  0xd1,  0x4b,  0x1d,  0x1a,  0x50,  0x00,  0xc9,  0x3e,  0x62,
-  0x7f,  0xf1,  0x55,  0xc9,  0xd7,  0xd9,  0x17,  0x4d,  0xfe,  0x8d,  0x37,  0xfb,
-  0x87,  0xf9,  0x57,  0xc6,  0xf5,  0xd1,  0xc5,  0x9c,  0x3d,  0x86,  0xc8,  0x5d,
-  0x05,  0x87,  0x9c,  0xa5,  0xcf,  0xcd,  0x7e,  0x6b,  0x74,  0xb6,  0xd6,  0x4b,
-  0xb8,  0x27,  0x70,  0xae,  0x87,  0x47,  0xf0,  0x07,  0x88,  0x35,  0xfb,  0x04,
-  0xbd,  0xb0,  0xd3,  0x64,  0xb9,  0xb5,  0x72,  0x42,  0xc8,  0xae,  0xa0,  0x12,
-  0x0e,  0x0f,  0x53,  0xeb,  0x5c,  0xf5,  0x7d,  0x27,  0xf0,  0x54,  0xe3,  0xe1,
-  0xed,  0x8f,  0xfd,  0x74,  0x97,  0xff,  0x00,  0x43,  0x35,  0xe7,  0x70,  0xbe,
-  0x4f,  0x43,  0x3c,  0xc6,  0xcb,  0x0d,  0x5e,  0x4d,  0x25,  0x16,  0xf4,  0xb5,
-  0xee,  0x9a,  0x5d,  0x53,  0xee,  0x0d,  0xd8,  0xf3,  0x1f,  0x0d,  0x7c,  0x12,
-  0xd7,  0xb5,  0x3d,  0x42,  0x31,  0xa9,  0x40,  0x34,  0xdb,  0x20,  0xc0,  0xc8,
-  0xee,  0xea,  0xce,  0x47,  0x70,  0xa0,  0x13,  0xcf,  0xb9,  0xe2,  0xbe,  0x87,
-  0xb7,  0x82,  0x3b,  0x4b,  0x78,  0xa0,  0x89,  0x42,  0x45,  0x12,  0x84,  0x45,
-  0x1d,  0x80,  0x18,  0x02,  0x97,  0x34,  0x9b,  0xab,  0xfa,  0x07,  0x25,  0xe1,
-  0xfc,  0x1e,  0x45,  0x09,  0x47,  0x0d,  0x76,  0xe5,  0xbb,  0x7a,  0xbd,  0x36,
-  0x5a,  0x24,  0xad,  0xf2,  0x22,  0xf7,  0x24,  0xcd,  0x19,  0xa8,  0xf7,  0x51,
-  0xba,  0xbe,  0x96,  0xc1,  0x71,  0xd2,  0x48,  0x22,  0x46,  0x76,  0xe0,  0x0e,
-  0x6b,  0x2a,  0x5b,  0xd9,  0x18,  0x17,  0x47,  0x11,  0xe4,  0xe3,  0x60,  0xeb,
-  0xf5,  0xa7,  0x49,  0x78,  0xef,  0xe7,  0xa9,  0x00,  0xa8,  0xe8,  0x08,  0xf7,
-  0x02,  0xaa,  0xf9,  0xc7,  0xfb,  0x89,  0xff,  0x00,  0x7c,  0x8a,  0xe9,  0x84,
-  0x2d,  0xb9,  0xc5,  0x56,  0xaf,  0x36,  0x89,  0x93,  0xc5,  0x7b,  0x22,  0x8d,
-  0xef,  0x20,  0x7d,  0xa7,  0xee,  0x37,  0x53,  0x5a,  0xd1,  0x4a,  0x26,  0x8d,
-  0x5d,  0x7a,  0x1a,  0xc2,  0xf3,  0x8f,  0xf7,  0x13,  0xfe,  0xf9,  0x15,  0x65,
-  0x2f,  0x1e,  0x34,  0x84,  0x28,  0x50,  0x09,  0xe4,  0x01,  0xef,  0x44,  0xe1,
-  0x7d,  0x85,  0x4e,  0xaf,  0x2e,  0xec,  0xd6,  0xa6,  0xcb,  0x28,  0x86,  0x36,
-  0x76,  0xe8,  0x29,  0x37,  0x56,  0x63,  0xde,  0x3c,  0x89,  0x30,  0x60,  0xa4,
-  0x0e,  0x80,  0x8f,  0x7a,  0xc2,  0x30,  0xe6,  0x3a,  0xa7,  0x53,  0x91,  0x0d,
-  0x96,  0xf6,  0x46,  0x05,  0xd2,  0x40,  0x9b,  0x8f,  0xdc,  0x5e,  0xa3,  0xde,
-  0x96,  0x2b,  0xd9,  0x14,  0x07,  0x77,  0x0f,  0xb4,  0xfd,  0xc6,  0xeb,  0xf5,
-  0xaa,  0xfe,  0x71,  0xfe,  0xe2,  0x7f,  0xdf,  0x22,  0x8f,  0x38,  0xff,  0x00,
-  0x71,  0x3f,  0xef,  0x91,  0x5d,  0x7c,  0xaa,  0xd6,  0xb1,  0xc1,  0xce,  0xef,
-  0x7b,  0x9b,  0xb1,  0xc8,  0x25,  0x45,  0x75,  0xe8,  0x46,  0x69,  0xd5,  0x95,
-  0x1d,  0xe3,  0xa0,  0x81,  0x46,  0x02,  0x9e,  0xa0,  0x0f,  0x72,  0x2b,  0x4b,
-  0x35,  0xc9,  0x28,  0xf2,  0x9d,  0xf0,  0xa9,  0xce,  0x85,  0x92,  0x41,  0x1a,
-  0x33,  0xb7,  0x40,  0x32,  0x6b,  0x2a,  0x5b,  0xd9,  0x1c,  0x17,  0x47,  0x09,
-  0x93,  0x8d,  0x83,  0xaf,  0xd6,  0x9d,  0x25,  0xe3,  0xbf,  0x9e,  0xa4,  0x02,
-  0xa3,  0xa0,  0x23,  0xdc,  0x55,  0x5f,  0x38,  0xff,  0x00,  0x71,  0x3f,  0xef,
-  0x91,  0x5b,  0xc2,  0x16,  0xdc,  0xe6,  0xa9,  0x57,  0x9b,  0x44,  0xc8,  0xea,
-  0x70,  0xa4,  0x88,  0x30,  0x09,  0xff,  0x00,  0xf5,  0xd3,  0x4d,  0xbb,  0x09,
-  0x84,  0x59,  0x1b,  0xbd,  0x7b,  0x56,  0x95,  0xb4,  0x66,  0x18,  0x42,  0x13,
-  0x92,  0x3d,  0x2a,  0xe5,  0x2b,  0x23,  0x2a,  0x70,  0x72,  0x6d,  0x32,  0x7a,
-  0xc8,  0x2a,  0x40,  0x9f,  0x20,  0x8f,  0xff,  0x00,  0x5d,  0x6a,  0xe6,  0xa3,
-  0xb9,  0x8c,  0xcf,  0x09,  0x40,  0x40,  0x27,  0xd6,  0xb1,  0x83,  0xe5,  0x3a,
-  0x6a,  0x47,  0x99,  0x5c,  0xc7,  0xa2,  0xa5,  0x5b,  0x76,  0x69,  0x8c,  0x59,
-  0x1b,  0xbf,  0x4a,  0x3e,  0xce,  0xde,  0x7f,  0x95,  0x91,  0xbb,  0xd7,  0xb5,
-  0x74,  0xdd,  0x1c,  0x3c,  0xac,  0x7a,  0xa9,  0x2d,  0x6f,  0x80,  0x7f,  0xcb,
-  0x1a,  0xd6,  0xa8,  0x6d,  0xe3,  0x30,  0xc2,  0xa8,  0x48,  0x24,  0x77,  0x15,
-  0x26,  0x6b,  0x9a,  0x6f,  0x99,  0x9d,  0xf4,  0xe3,  0xca,  0x8c,  0xb6,  0x52,
-  0x1a,  0xe3,  0x20,  0xff,  0x00,  0x96,  0x15,  0x5e,  0xb6,  0x2e,  0x23,  0x33,
-  0x44,  0xc8,  0x08,  0x04,  0xd6,  0x67,  0xd9,  0xdb,  0xcf,  0xf2,  0xb2,  0x37,
-  0x7a,  0xf6,  0xad,  0xa1,  0x24,  0xd1,  0xcb,  0x52,  0x0e,  0x2d,  0x58,  0x8a,
-  0xa7,  0x0a,  0x48,  0x83,  0x00,  0x9f,  0xff,  0x00,  0x5d,  0x34,  0xdb,  0xb2,
-  0xcc,  0x22,  0xc8,  0xdd,  0xeb,  0xda,  0xb4,  0xad,  0xa3,  0x30,  0xc2,  0xaa,
-  0x4e,  0x48,  0xf4,  0xa2,  0x52,  0xb2,  0x0a,  0x70,  0x72,  0x6d,  0x32,  0x7a,
-  0x29,  0xa4,  0xd1,  0x9a,  0xe5,  0xb1,  0xde,  0x3a,  0x8a,  0x6e,  0x73,  0x41,
-  0x34,  0x58,  0x0e,  0x7f,  0xe2,  0x1f,  0xfc,  0x88,  0xfa,  0xe7,  0xfd,  0x7a,
-  0xbf,  0xf2,  0xaf,  0x95,  0xab,  0xeb,  0x2f,  0x18,  0x58,  0x4b,  0xaa,  0xf8,
-  0x57,  0x56,  0xb4,  0x80,  0x6e,  0x9a,  0x6b,  0x69,  0x15,  0x17,  0xd5,  0xb6,
-  0x9c,  0x0f,  0xce,  0xbe,  0x4e,  0x65,  0x2a,  0x48,  0x20,  0x82,  0x38,  0x20,
-  0xf6,  0xaf,  0xc1,  0x7c,  0x46,  0x84,  0x96,  0x32,  0x84,  0xed,  0xa3,  0x8b,
-  0x5f,  0x73,  0xff,  0x00,  0x82,  0x8d,  0x20,  0x25,  0x7d,  0x5d,  0xe0,  0x5f,
-  0xf9,  0x12,  0xf4,  0x2f,  0xfa,  0xf2,  0x87,  0xff,  0x00,  0x40,  0x15,  0xf2,
-  0x9a,  0x23,  0x48,  0xea,  0x88,  0xa5,  0x9d,  0x8e,  0x02,  0x81,  0x92,  0x4d,
-  0x7d,  0x69,  0xe1,  0x8b,  0x19,  0x34,  0xbf,  0x0d,  0xe9,  0x76,  0x73,  0x71,
-  0x2c,  0x16,  0xd1,  0xc6,  0xe3,  0xd0,  0x85,  0x00,  0xd5,  0x78,  0x73,  0x09,
-  0x3c,  0x56,  0x22,  0x76,  0xd1,  0x45,  0x2f,  0xc7,  0xfe,  0x00,  0x4c,  0xd0,
-  0xba,  0xff,  0x00,  0x8f,  0x69,  0xbf,  0xdc,  0x3f,  0xca,  0xbe,  0x39,  0xaf,
-  0xb1,  0xe5,  0x5f,  0x32,  0x27,  0x4c,  0xe3,  0x72,  0x91,  0x9a,  0xf9,  0x03,
-  0x50,  0xb1,  0x9b,  0x4c,  0xbe,  0xb8,  0xb4,  0x9d,  0x0a,  0x4d,  0x04,  0x86,
-  0x37,  0x53,  0xd8,  0x83,  0x8a,  0xed,  0xf1,  0x22,  0x12,  0xff,  0x00,  0x65,
-  0x9d,  0xb4,  0xf7,  0xd7,  0xfe,  0x92,  0x10,  0x2b,  0xd7,  0xd2,  0x5f,  0x05,
-  0xbf,  0xe4,  0x9f,  0x58,  0xff,  0x00,  0xd7,  0x49,  0x7f,  0xf4,  0x33,  0x5f,
-  0x36,  0xd7,  0xd3,  0x9f,  0x0a,  0x74,  0xe9,  0xb4,  0xbf,  0x01,  0xe9,  0x91,
-  0x4e,  0xa5,  0x24,  0x75,  0x69,  0x76,  0x9e,  0xa0,  0x33,  0x12,  0x3f,  0x42,
-  0x2b,  0xc3,  0xf0,  0xf6,  0x12,  0x96,  0x69,  0x52,  0x49,  0x68,  0xa0,  0xff,
-  0x00,  0x19,  0x44,  0x72,  0xd8,  0xeb,  0xe8,  0xa6,  0xe6,  0x8c,  0xd7,  0xf4,
-  0x3d,  0x8c,  0x87,  0x51,  0x4d,  0xcd,  0x19,  0xa2,  0xc0,  0x65,  0xb2,  0x90,
-  0xd7,  0x19,  0x04,  0x7f,  0xfb,  0x42,  0xab,  0xd6,  0xc5,  0xc4,  0x66,  0x68,
-  0x59,  0x07,  0x04,  0xfa,  0xd6,  0x67,  0xd9,  0xdb,  0xcf,  0xf2,  0xb2,  0x37,
-  0x7a,  0xf6,  0xae,  0xa8,  0x4a,  0xe8,  0xe0,  0xa9,  0x07,  0x16,  0xac,  0x45,
-  0x53,  0x85,  0x24,  0x41,  0x80,  0x4f,  0xff,  0x00,  0xae,  0x9a,  0x6d,  0xd9,
-  0x66,  0x11,  0x64,  0x6e,  0xf5,  0xed,  0x5a,  0x76,  0xd1,  0x98,  0x21,  0x0a,
-  0x48,  0x27,  0xda,  0x89,  0x4a,  0xc8,  0x29,  0xc1,  0xc9,  0xb4,  0xc9,  0xab,
-  0x20,  0xa9,  0x02,  0x7c,  0x82,  0x3f,  0xfd,  0x75,  0xab,  0x9a,  0x8a,  0xe6,
-  0x33,  0x34,  0x45,  0x41,  0xc1,  0xf7,  0xac,  0x60,  0xf9,  0x4e,  0x9a,  0x91,
-  0xe6,  0x46,  0x45,  0x15,  0x28,  0xb7,  0x66,  0x98,  0xc5,  0x91,  0xb8,  0x77,
-  0xed,  0x47,  0xd9,  0xdb,  0xcf,  0xf2,  0xb2,  0x37,  0x7a,  0xf6,  0xae,  0x9b,
-  0xa3,  0x87,  0x95,  0x8f,  0x55,  0x25,  0xad,  0xf0,  0x0f,  0xf9,  0x63,  0x5a,
-  0xd5,  0x0d,  0xba,  0x18,  0x61,  0x54,  0x24,  0x12,  0x3d,  0x2a,  0x4c,  0xd7,
-  0x34,  0xdf,  0x33,  0x3b,  0xe9,  0xc7,  0x95,  0x19,  0x6c,  0xa4,  0x35,  0xc6,
-  0x41,  0xff,  0x00,  0x2c,  0x2a,  0xbd,  0x6c,  0x5c,  0x46,  0x66,  0x85,  0x90,
-  0x1c,  0x13,  0xeb,  0x59,  0x9f,  0x67,  0x6f,  0x3f,  0xca,  0xc8,  0xdd,  0xfa,
-  0x56,  0xd0,  0x92,  0x68,  0xe5,  0xa9,  0x06,  0x9a,  0xb1,  0xa0,  0xd6,  0xc1,
-  0xae,  0x04,  0xb9,  0x39,  0x1d,  0xaa,  0x6a,  0x28,  0xae,  0x76,  0xdb,  0x3a,
-  0xd2,  0xb6,  0xc1,  0x45,  0x14,  0x52,  0x19,  0x0a,  0xdb,  0x05,  0xb8,  0x32,
-  0xe4,  0xe4,  0xf6,  0xa3,  0xec,  0xc3,  0xed,  0x1e,  0x6e,  0x4e,  0x7d,  0x2a,
-  0x6a,  0x2a,  0xb9,  0x99,  0x3c,  0xa8,  0x28,  0xa2,  0x8a,  0x92,  0x82,  0xa1,
-  0xfb,  0x30,  0xfb,  0x47,  0x9b,  0x93,  0x9f,  0x4a,  0x9a,  0x8a,  0x69,  0xd8,
-  0x4d,  0x5f,  0x72,  0x16,  0xb6,  0x0d,  0x70,  0x25,  0xc9,  0xc8,  0xed,  0x53,
-  0x51,  0x45,  0x0d,  0xb6,  0x09,  0x5b,  0x60,  0xa2,  0x8a,  0x29,  0x0c,  0x28,
-  0xa2,  0x8a,  0x00,  0x2b,  0x83,  0xf1,  0x57,  0xc1,  0xdd,  0x1b,  0xc4,  0xb7,
-  0xaf,  0x79,  0x1b,  0xcb,  0xa7,  0x5d,  0x48,  0x73,  0x21,  0x80,  0x02,  0x8e,
-  0x7d,  0x4a,  0x9e,  0xff,  0x00,  0x42,  0x2b,  0xbc,  0xa2,  0xbc,  0xfc,  0x76,
-  0x5f,  0x85,  0xcc,  0xa9,  0xfb,  0x1c,  0x5d,  0x35,  0x38,  0xf9,  0xfe,  0x8f,
-  0x75,  0xf2,  0x1a,  0x6d,  0x1c,  0x3f,  0x84,  0xbe,  0x11,  0xe8,  0xde,  0x16,
-  0xbb,  0x4b,  0xc2,  0xd2,  0x5f,  0xde,  0x27,  0x29,  0x24,  0xf8,  0xda,  0x87,
-  0xd5,  0x54,  0x77,  0xf7,  0x39,  0xae,  0xe2,  0x8a,  0x29,  0xe0,  0xb0,  0x18,
-  0x5c,  0xba,  0x97,  0xb1,  0xc2,  0x53,  0x50,  0x8f,  0x97,  0xeb,  0xd5,  0xfc,
-  0xc2,  0xed,  0x85,  0x71,  0xfe,  0x31,  0xf8,  0x5f,  0xa4,  0x78,  0xc6,  0x6f,
-  0xb4,  0xcd,  0xe6,  0x5a,  0x5e,  0xe3,  0x06,  0xe2,  0x0c,  0x65,  0xc7,  0x6d,
-  0xc0,  0xf5,  0xfe,  0x7e,  0xf5,  0xd8,  0x51,  0x55,  0x8c,  0xc1,  0x61,  0xf1,
-  0xf4,  0x9d,  0x0c,  0x54,  0x14,  0xe2,  0xfa,  0x3f,  0xeb,  0x46,  0x17,  0x68,
-  0xf3,  0xbf,  0x0f,  0x7c,  0x11,  0xd1,  0x74,  0x6b,  0xc4,  0xb9,  0xb9,  0x96,
-  0x5d,  0x49,  0xd0,  0xe5,  0x63,  0x94,  0x05,  0x8f,  0x3e,  0xa5,  0x47,  0x5f,
-  0xc4,  0xe3,  0xda,  0xbd,  0x13,  0xa5,  0x14,  0x56,  0x38,  0x1c,  0xb7,  0x07,
-  0x96,  0x41,  0xd3,  0xc1,  0xd3,  0x50,  0x4f,  0x7b,  0x75,  0xf5,  0x7b,  0xb0,
-  0x6d,  0xb0,  0xa2,  0x8a,  0x2b,  0xd3,  0x10,  0x51,  0x45,  0x14,  0x00,  0x54,
-  0x3f,  0x66,  0x1f,  0x68,  0xf3,  0x72,  0x73,  0xe9,  0x53,  0x51,  0x4d,  0x3b,
-  0x09,  0xab,  0xee,  0x42,  0xd6,  0xc1,  0xae,  0x04,  0xb9,  0x39,  0x1d,  0xaa,
-  0x6a,  0x28,  0xa1,  0xb6,  0xc1,  0x2b,  0x6c,  0x14,  0x51,  0x45,  0x21,  0x90,
-  0xad,  0xb0,  0x5b,  0x83,  0x2e,  0x4e,  0x4f,  0x6a,  0x3e,  0xcc,  0x3e,  0xd1,
-  0xe6,  0xe4,  0xe7,  0xd2,  0xa6,  0xa2,  0xab,  0x99,  0x93,  0xca,  0x82,  0x8a,
-  0x28,  0xa9,  0x28,  0x2a,  0x1f,  0xb3,  0x0f,  0xb4,  0x79,  0xb9,  0x39,  0xf4,
-  0xa9,  0xa8,  0xa6,  0x9d,  0x84,  0xd5,  0xf7,  0x3e,  0x20,  0xff,  0x00,  0x87,
-  0xa6,  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,
-  0xfe,  0x1e,  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,
-  0xbe,  0x17,  0xfe,  0xc6,  0xb2,  0xff,  0x00,  0x9f,  0x64,  0xa7,  0x47,  0xa2,
-  0x59,  0x31,  0xe6,  0xd9,  0x31,  0x45,  0x8e,  0x9e,  0x44,  0x7d,  0xcd,  0xff,
-  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,  0xfe,  0x05,  0x45,
-  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,
-  0x15,  0x7c,  0x3b,  0xfd,  0x87,  0x61,  0xff,  0x00,  0x3e,  0xb1,  0xfe,  0x54,
-  0xd9,  0x34,  0x6b,  0x05,  0x1c,  0x5b,  0x47,  0x9f,  0xa5,  0x16,  0x0e,  0x44,
-  0x7d,  0xc9,  0xff,  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,
-  0xfe,  0x05,  0x45,  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,
-  0x1f,  0xf8,  0x15,  0x15,  0x7c,  0x2f,  0xfd,  0x8d,  0x65,  0xff,  0x00,  0x3e,
-  0xc9,  0xf9,  0x53,  0xe3,  0xd1,  0x2c,  0x4f,  0x26,  0xd9,  0x31,  0xf4,  0xa2,
-  0xc1,  0xc8,  0x8f,  0xb9,  0x7f,  0xe1,  0xe9,  0xbe,  0x16,  0xff,  0x00,  0xa1,
-  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xa8,  0xff,  0x00,  0x87,  0xa6,  0xf8,
-  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xaf,  0x87,  0x7f,
-  0xb0,  0xec,  0x3f,  0xe7,  0xd6,  0x3f,  0xca,  0x99,  0x26,  0x8d,  0x62,  0x38,
-  0x16,  0xc9,  0x9a,  0x2c,  0x1c,  0x88,  0xfb,  0x97,  0xfe,  0x1e,  0x9b,  0xe1,
-  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0x8f,  0xf8,  0x7a,  0x6f,
-  0x85,  0xbf,  0xe8,  0x47,  0xd6,  0x3f,  0xf0,  0x2a,  0x2a,  0xf8,  0x5f,  0xfb,
-  0x1a,  0xcb,  0xfe,  0x7d,  0x93,  0xf2,  0xa9,  0x23,  0xd1,  0x2c,  0x48,  0xc9,
-  0xb6,  0x4f,  0xca,  0x8b,  0x07,  0x22,  0x3e,  0xe4,  0xff,  0x00,  0x87,  0xa6,
-  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,  0xfe,
-  0x1e,  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0xbe,
-  0x1d,  0xfe,  0xc3,  0xb0,  0xff,  0x00,  0x9f,  0x58,  0xff,  0x00,  0x2a,  0x64,
-  0x9a,  0x35,  0x88,  0x38,  0x16,  0xc9,  0xf9,  0x51,  0x60,  0xe4,  0x47,  0xdc,
-  0xbf,  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,
-  0x54,  0x7f,  0xc3,  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,  0x3e,  0xb1,  0xff,
-  0x00,  0x81,  0x51,  0x57,  0xc2,  0xff,  0x00,  0xd8,  0xd6,  0x5f,  0xf3,  0xec,
-  0x9f,  0x95,  0x48,  0x9a,  0x1d,  0x89,  0x19,  0x36,  0xc9,  0xf9,  0x51,  0x60,
-  0xe4,  0x47,  0xdc,  0x9f,  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,
-  0x7f,  0xe0,  0x54,  0x54,  0x7f,  0xc3,  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,
-  0x3e,  0xb1,  0xff,  0x00,  0x81,  0x51,  0x57,  0xc3,  0xbf,  0xd8,  0x76,  0x1f,
-  0xf3,  0xeb,  0x1f,  0xe5,  0x51,  0xbe,  0x8d,  0x63,  0x9c,  0x0b,  0x64,  0xfc,
-  0xa8,  0xb0,  0x72,  0x23,  0xee,  0x6f,  0xf8,  0x7a,  0x6f,  0x85,  0xbf,  0xe8,
-  0x47,  0xd6,  0x3f,  0xf0,  0x2a,  0x2a,  0x3f,  0xe1,  0xe9,  0xbe,  0x16,  0xff,
-  0x00,  0xa1,  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xab,  0xe1,  0x7f,  0xec,
-  0x7b,  0x2f,  0xf9,  0xf6,  0x4f,  0xca,  0x9b,  0x2e,  0x9d,  0xa7,  0xdb,  0xed,
-  0x53,  0x67,  0xe6,  0xc8,  0xc0,  0x90,  0xb1,  0xae,  0x4e,  0x3d,  0x68,  0xb0,
-  0x72,  0x23,  0xee,  0xaf,  0xf8,  0x7a,  0x6f,  0x85,  0xbf,  0xe8,  0x47,  0xd6,
-  0x3f,  0xf0,  0x2a,  0x2a,  0x3f,  0xe1,  0xe9,  0xbe,  0x16,  0xff,  0x00,  0xa1,
-  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xab,  0xe1,  0x1f,  0x23,  0x4b,  0xd8,
-  0x1b,  0xec,  0x44,  0x8d,  0xbb,  0x9b,  0x09,  0xf7,  0x06,  0x48,  0xc9,  0xe7,
-  0xd8,  0xfe,  0x54,  0x3d,  0x9e,  0x9e,  0x2e,  0x04,  0x66,  0xcb,  0x60,  0x27,
-  0x68,  0x72,  0xbf,  0x29,  0x3f,  0x5c,  0xd1,  0x60,  0xe4,  0x47,  0xdd,  0xdf,
-  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,  0x54,
-  0x7f,  0xc3,  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,  0x3e,  0xb1,  0xff,  0x00,
-  0x81,  0x51,  0x57,  0xc1,  0x82,  0xdf,  0x4e,  0x1b,  0xb7,  0xd9,  0x98,  0x88,
-  0x19,  0xda,  0xeb,  0xc9,  0xe7,  0x1c,  0x73,  0xea,  0x45,  0x4d,  0x1d,  0x9e,
-  0x9a,  0x46,  0x0d,  0x91,  0x12,  0x02,  0x41,  0x8c,  0xaf,  0xcd,  0x9c,  0x67,
-  0xd7,  0xd2,  0x8b,  0x07,  0x22,  0x3e,  0xed,  0xff,  0x00,  0x87,  0xa6,  0xf8,
-  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,  0xfe,  0x1e,
-  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0xbe,  0x16,
-  0xb7,  0xd3,  0xf4,  0xeb,  0x86,  0x65,  0xfb,  0x1f,  0x96,  0xea,  0x01,  0x2b,
-  0x22,  0xe0,  0xe0,  0xf7,  0xa7,  0x36,  0x8f,  0x62,  0x49,  0xc5,  0xb2,  0x62,
-  0x8b,  0x07,  0x22,  0x3e,  0xe7,  0xff,  0x00,  0x87,  0xa6,  0xf8,  0x5b,  0xfe,
-  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xa3,  0xfe,  0x1e,  0x9b,  0xe1,
-  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,  0x8a,  0xbe,  0x17,  0xfe,  0xc6,
-  0xb2,  0x3f,  0xf2,  0xec,  0x95,  0x30,  0xd0,  0xec,  0x40,  0xff,  0x00,  0x8f,
-  0x64,  0xa2,  0xc1,  0xc8,  0x8f,  0xb8,  0xbf,  0xe1,  0xe9,  0xbe,  0x16,  0xff,
-  0x00,  0xa1,  0x1f,  0x58,  0xff,  0x00,  0xc0,  0xa8,  0xa8,  0xff,  0x00,  0x87,
-  0xa6,  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,  0xaf,
-  0x87,  0x7f,  0xb1,  0x2c,  0x07,  0xfc,  0xba,  0xc7,  0xf9,  0x54,  0x27,  0x47,
-  0xb2,  0x27,  0xfe,  0x3d,  0x92,  0x8b,  0x07,  0x22,  0x3e,  0xe8,  0xff,  0x00,
-  0x87,  0xa6,  0xf8,  0x5b,  0xfe,  0x84,  0x7d,  0x63,  0xff,  0x00,  0x02,  0xa2,
-  0xa3,  0xfe,  0x1e,  0x9b,  0xe1,  0x6f,  0xfa,  0x11,  0xf5,  0x8f,  0xfc,  0x0a,
-  0x8a,  0xbe,  0x17,  0x1a,  0x2d,  0x91,  0x38,  0xfb,  0x32,  0x54,  0xdf,  0xd8,
-  0x76,  0x1f,  0xf3,  0xea,  0x9f,  0x95,  0x16,  0x0e,  0x44,  0x7d,  0xc5,  0xff,
-  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,  0xfe,  0x05,  0x45,
-  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,
-  0x15,  0x7c,  0x3a,  0x74,  0x4b,  0x00,  0x33,  0xf6,  0x58,  0xff,  0x00,  0x2a,
-  0x84,  0xe8,  0xd6,  0x5f,  0xf3,  0xec,  0x94,  0x58,  0x39,  0x11,  0xf7,  0x47,
-  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,  0x15,
-  0x1f,  0xf0,  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,
-  0x55,  0xf0,  0xc2,  0xe8,  0xb6,  0x4c,  0x40,  0xfb,  0x32,  0x54,  0xbf,  0xd8,
-  0x76,  0x1f,  0xf3,  0xea,  0x94,  0x58,  0x39,  0x11,  0xf7,  0x17,  0xfc,  0x3d,
-  0x37,  0xc2,  0xdf,  0xf4,  0x23,  0xeb,  0x1f,  0xf8,  0x15,  0x15,  0x1f,  0xf0,
-  0xf4,  0xdf,  0x0b,  0x7f,  0xd0,  0x8f,  0xac,  0x7f,  0xe0,  0x54,  0x55,  0xf0,
-  0xe3,  0x68,  0xb6,  0x0a,  0x09,  0xfb,  0x2c,  0x7f,  0x95,  0x45,  0xfd,  0x8d,
-  0x65,  0xff,  0x00,  0x3e,  0xc9,  0x45,  0x83,  0x91,  0x1f,  0x74,  0x7f,  0xc3,
-  0xd3,  0x7c,  0x2d,  0xff,  0x00,  0x42,  0x3e,  0xb1,  0xff,  0x00,  0x81,  0x51,
-  0x51,  0xff,  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,  0xc7,  0xfe,
-  0x05,  0x45,  0x5f,  0x0c,  0x26,  0x89,  0x64,  0xcd,  0xff,  0x00,  0x1e,  0xc9,
-  0x52,  0xff,  0x00,  0x61,  0xd8,  0x7f,  0xcf,  0xac,  0x7f,  0x95,  0x16,  0x0e,
-  0x44,  0x7d,  0xc5,  0xff,  0x00,  0x0f,  0x4d,  0xf0,  0xb7,  0xfd,  0x08,  0xfa,
-  0xc7,  0xfe,  0x05,  0x45,  0x47,  0xfc,  0x3d,  0x37,  0xc2,  0xdf,  0xf4,  0x23,
-  0xeb,  0x1f,  0xf8,  0x15,  0x15,  0x7c,  0x38,  0xfa,  0x2d,  0x82,  0xaf,  0xfc,
-  0x7a,  0xc7,  0xf9,  0x54,  0x5f,  0xd8,  0xd6,  0x5f,  0xf3,  0xec,  0x94,  0x58,
-  0x39,  0x11,  0x72,  0xa7,  0x45,  0xda,  0xb8,  0xa8,  0xe3,  0x5c,  0xb6,  0x7d,
-  0x2a,  0x5a,  0xa2,  0xc2,  0xa1,  0x66,  0xdc,  0xd9,  0xa7,  0xc8,  0xd8,  0x18,
-  0xf5,  0xa8,  0xa8,  0x01,  0x40,  0xc9,  0xa9,  0xd4,  0x6d,  0x18,  0xa8,  0xe2,
-  0x5e,  0x73,  0x52,  0x50,  0x00,  0x4e,  0x05,  0x40,  0xc7,  0x71,  0xcd,  0x49,
-  0x2b,  0x71,  0x8a,  0x8a,  0x80,  0x14,  0x0c,  0x9c,  0x54,  0xe0,  0x60,  0x62,
-  0xa3,  0x89,  0x7b,  0xd4,  0x94,  0x00,  0x13,  0x80,  0x4d,  0x40,  0x4e,  0x4e,
-  0x69,  0xf2,  0xb7,  0x6a,  0x8e,  0x80,  0x15,  0x46,  0xe3,  0x8a,  0x9e,  0x99,
-  0x1a,  0xe0,  0x67,  0xd6,  0x9f,  0x40,  0x08,  0xc7,  0x68,  0xcd,  0x41,  0x4f,
-  0x91,  0xb2,  0x71,  0xe9,  0x4c,  0xa0,  0x07,  0x22,  0xee,  0x6f,  0x6a,  0x27,
-  0xb5,  0x59,  0xa4,  0x49,  0x37,  0xbc,  0x6e,  0xbc,  0x06,  0x43,  0x8c,  0x8f,
-  0x43,  0xed,  0x52,  0x46,  0xb8,  0x5f,  0x73,  0x4e,  0xa0,  0x0a,  0xa6,  0xca,
-  0x38,  0xa2,  0x95,  0x41,  0x6f,  0xde,  0x2e,  0xc3,  0xcf,  0x6c,  0x93,  0xff,
-  0x00,  0xb3,  0x1a,  0x87,  0xec,  0x60,  0xca,  0xae,  0xd2,  0x48,  0xe1,  0x4e,
-  0x42,  0x12,  0x36,  0x83,  0xf9,  0x55,  0xa9,  0x1b,  0x73,  0x7b,  0x0a,  0x6d,
-  0x00,  0x57,  0x8b,  0x49,  0xb7,  0x0c,  0xfb,  0x53,  0xcb,  0x0c,  0x00,  0x21,
-  0x38,  0xe8,  0x72,  0x0f,  0xd6,  0xa6,  0x5d,  0x39,  0x17,  0x90,  0xf2,  0x79,
-  0x99,  0x2c,  0x64,  0x27,  0x2c,  0x4e,  0xdc,  0x7e,  0x82,  0xac,  0xa2,  0xed,
-  0x5a,  0x5a,  0x00,  0xad,  0x1d,  0xaa,  0xdb,  0x16,  0x6f,  0x31,  0xe5,  0x91,
-  0xc0,  0x05,  0xe4,  0x39,  0x38,  0x1d,  0xbf,  0x5a,  0x5a,  0x73,  0xb6,  0xe6,
-  0xa6,  0xf5,  0xa0,  0x07,  0xc4,  0xb9,  0x39,  0xf4,  0xa9,  0x69,  0x14,  0x6d,
-  0x18,  0xa5,  0xe9,  0x40,  0x0c,  0x95,  0xb0,  0x31,  0x51,  0x52,  0xb1,  0xdc,
-  0x49,  0xa0,  0x0c,  0x9c,  0x50,  0x03,  0xe2,  0x5e,  0xf5,  0x25,  0x00,  0x60,
-  0x62,  0x82,  0x70,  0x33,  0x40,  0x11,  0xca,  0xdd,  0xaa,  0x3a,  0x52,  0x72,
-  0x73,  0x42,  0x8d,  0xc4,  0x0a,  0x00,  0x92,  0x25,  0xc0,  0xcd,  0x3e,  0x8e,
-  0x94,  0x8c,  0x76,  0x82,  0x68,  0x02,  0x39,  0x5b,  0x27,  0x1e,  0x94,  0xca,
-  0x3a,  0xd3,  0x91,  0x77,  0x35,  0x00,  0x49,  0x1a,  0xe1,  0x7d,  0xcd,  0x3a,
-  0x8a,  0x47,  0x6d,  0xab,  0x40,  0x11,  0xc8,  0xd9,  0x6f,  0x61,  0x4c,  0xa2,
-  0x9d,  0x1a,  0xee,  0x6f,  0x61,  0x40,  0x1f,  0xff,  0xd9
-};
diff --git a/camera/libcameraservice/FakeCamera.cpp b/camera/libcameraservice/FakeCamera.cpp
deleted file mode 100644
index 6749899..0000000
--- a/camera/libcameraservice/FakeCamera.cpp
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "FakeCamera"
-#include <utils/Log.h>
-
-#include <string.h>
-#include <stdlib.h>
-#include <utils/String8.h>
-
-#include "FakeCamera.h"
-
-
-namespace android {
-
-// TODO: All this rgb to yuv should probably be in a util class.
-
-// TODO: I think something is wrong in this class because the shadow is kBlue
-// and the square color should alternate between kRed and kGreen. However on the
-// emulator screen these are all shades of gray. Y seems ok but the U and V are
-// probably not.
-
-static int tables_initialized = 0;
-uint8_t *gYTable, *gCbTable, *gCrTable;
-
-static int
-clamp(int  x)
-{
-    if (x > 255) return 255;
-    if (x < 0)   return 0;
-    return x;
-}
-
-/* the equation used by the video code to translate YUV to RGB looks like this
- *
- *    Y  = (Y0 - 16)*k0
- *    Cb = Cb0 - 128
- *    Cr = Cr0 - 128
- *
- *    G = ( Y - k1*Cr - k2*Cb )
- *    R = ( Y + k3*Cr )
- *    B = ( Y + k4*Cb )
- *
- */
-
-static const double  k0 = 1.164;
-static const double  k1 = 0.813;
-static const double  k2 = 0.391;
-static const double  k3 = 1.596;
-static const double  k4 = 2.018;
-
-/* let's try to extract the value of Y
- *
- *   G + k1/k3*R + k2/k4*B = Y*( 1 + k1/k3 + k2/k4 )
- *
- *   Y  = ( G + k1/k3*R + k2/k4*B ) / (1 + k1/k3 + k2/k4)
- *   Y0 = ( G0 + k1/k3*R0 + k2/k4*B0 ) / ((1 + k1/k3 + k2/k4)*k0) + 16
- *
- * let define:
- *   kYr = k1/k3
- *   kYb = k2/k4
- *   kYy = k0 * ( 1 + kYr + kYb )
- *
- * we have:
- *    Y  = ( G + kYr*R + kYb*B )
- *    Y0 = clamp[ Y/kYy + 16 ]
- */
-
-static const double kYr = k1/k3;
-static const double kYb = k2/k4;
-static const double kYy = k0*( 1. + kYr + kYb );
-
-static void
-initYtab( void )
-{
-    const  int imax = (int)( (kYr + kYb)*(31 << 2) + (61 << 3) + 0.1 );
-    int    i;
-
-    gYTable = (uint8_t *)malloc(imax);
-
-    for(i=0; i<imax; i++) {
-        int  x = (int)(i/kYy + 16.5);
-        if (x < 16) x = 16;
-        else if (x > 235) x = 235;
-        gYTable[i] = (uint8_t) x;
-    }
-}
-
-/*
- *   the source is RGB565, so adjust for 8-bit range of input values:
- *
- *   G = (pixels >> 3) & 0xFC;
- *   R = (pixels >> 8) & 0xF8;
- *   B = (pixels & 0x1f) << 3;
- *
- *   R2 = (pixels >> 11)      R = R2*8
- *   B2 = (pixels & 0x1f)     B = B2*8
- *
- *   kYr*R = kYr2*R2 =>  kYr2 = kYr*8
- *   kYb*B = kYb2*B2 =>  kYb2 = kYb*8
- *
- *   we want to use integer multiplications:
- *
- *   SHIFT1 = 9
- *
- *   (ALPHA*R2) >> SHIFT1 == R*kYr  =>  ALPHA = kYr*8*(1 << SHIFT1)
- *
- *   ALPHA = kYr*(1 << (SHIFT1+3))
- *   BETA  = kYb*(1 << (SHIFT1+3))
- */
-
-static const int  SHIFT1  = 9;
-static const int  ALPHA   = (int)( kYr*(1 << (SHIFT1+3)) + 0.5 );
-static const int  BETA    = (int)( kYb*(1 << (SHIFT1+3)) + 0.5 );
-
-/*
- *  now let's try to get the values of Cb and Cr
- *
- *  R-B = (k3*Cr - k4*Cb)
- *
- *    k3*Cr = k4*Cb + (R-B)
- *    k4*Cb = k3*Cr - (R-B)
- *
- *  R-G = (k1+k3)*Cr + k2*Cb
- *      = (k1+k3)*Cr + k2/k4*(k3*Cr - (R-B)/k0)
- *      = (k1 + k3 + k2*k3/k4)*Cr - k2/k4*(R-B)
- *
- *  kRr*Cr = (R-G) + kYb*(R-B)
- *
- *  Cr  = ((R-G) + kYb*(R-B))/kRr
- *  Cr0 = clamp(Cr + 128)
- */
-
-static const double  kRr = (k1 + k3 + k2*k3/k4);
-
-static void
-initCrtab( void )
-{
-    uint8_t *pTable;
-    int i;
-
-    gCrTable = (uint8_t *)malloc(768*2);
-
-    pTable = gCrTable + 384;
-    for(i=-384; i<384; i++)
-        pTable[i] = (uint8_t) clamp( i/kRr + 128.5 );
-}
-
-/*
- *  B-G = (k2 + k4)*Cb + k1*Cr
- *      = (k2 + k4)*Cb + k1/k3*(k4*Cb + (R-B))
- *      = (k2 + k4 + k1*k4/k3)*Cb + k1/k3*(R-B)
- *
- *  kBb*Cb = (B-G) - kYr*(R-B)
- *
- *  Cb   = ((B-G) - kYr*(R-B))/kBb
- *  Cb0  = clamp(Cb + 128)
- *
- */
-
-static const double  kBb = (k2 + k4 + k1*k4/k3);
-
-static void
-initCbtab( void )
-{
-    uint8_t *pTable;
-    int i;
-
-    gCbTable = (uint8_t *)malloc(768*2);
-
-    pTable = gCbTable + 384;
-    for(i=-384; i<384; i++)
-        pTable[i] = (uint8_t) clamp( i/kBb + 128.5 );
-}
-
-/*
- *   SHIFT2 = 16
- *
- *   DELTA = kYb*(1 << SHIFT2)
- *   GAMMA = kYr*(1 << SHIFT2)
- */
-
-static const int  SHIFT2 = 16;
-static const int  DELTA  = kYb*(1 << SHIFT2);
-static const int  GAMMA  = kYr*(1 << SHIFT2);
-
-int32_t ccrgb16toyuv_wo_colorkey(uint8_t *rgb16,uint8_t *yuv422,uint32_t *param,uint8_t *table[])
-{
-    uint16_t *inputRGB = (uint16_t*)rgb16;
-    uint8_t *outYUV =  yuv422;
-    int32_t width_dst = param[0];
-    int32_t height_dst = param[1];
-    int32_t pitch_dst = param[2];
-    int32_t mheight_dst = param[3];
-    int32_t pitch_src = param[4];
-    uint8_t *y_tab = table[0];
-    uint8_t *cb_tab = table[1];
-    uint8_t *cr_tab = table[2];
-
-    int32_t size16 = pitch_dst*mheight_dst;
-    int32_t i,j,count;
-    int32_t ilimit,jlimit;
-    uint8_t *tempY,*tempU,*tempV;
-    uint16_t pixels;
-    int   tmp;
-uint32_t temp;
-
-    tempY = outYUV;
-    tempU = outYUV + (height_dst * pitch_dst);
-    tempV = tempU + 1;
-
-    jlimit = height_dst;
-    ilimit = width_dst;
-
-    for(j=0; j<jlimit; j+=1)
-    {
-        for (i=0; i<ilimit; i+=2)
-        {
-            int32_t   G_ds = 0, B_ds = 0, R_ds = 0;
-            uint8_t   y0, y1, u, v;
-
-            pixels =  inputRGB[i];
-            temp = (BETA*(pixels & 0x001F) + ALPHA*(pixels>>11) );
-            y0   = y_tab[(temp>>SHIFT1) + ((pixels>>3) & 0x00FC)];
-
-            G_ds    += (pixels>>1) & 0x03E0;
-            B_ds    += (pixels<<5) & 0x03E0;
-            R_ds    += (pixels>>6) & 0x03E0;
-
-            pixels =  inputRGB[i+1];
-            temp = (BETA*(pixels & 0x001F) + ALPHA*(pixels>>11) );
-            y1   = y_tab[(temp>>SHIFT1) + ((pixels>>3) & 0x00FC)];
-
-            G_ds    += (pixels>>1) & 0x03E0;
-            B_ds    += (pixels<<5) & 0x03E0;
-            R_ds    += (pixels>>6) & 0x03E0;
-
-            R_ds >>= 1;
-            B_ds >>= 1;
-            G_ds >>= 1;
-
-            tmp = R_ds - B_ds;
-
-            u = cb_tab[(((B_ds-G_ds)<<SHIFT2) - GAMMA*tmp)>>(SHIFT2+2)];
-            v = cr_tab[(((R_ds-G_ds)<<SHIFT2) + DELTA*tmp)>>(SHIFT2+2)];
-
-            tempY[0] = y0;
-            tempY[1] = y1;
-            tempU[0] = u;
-            tempV[0] = v;
-
-            tempY += 2;
-            tempU += 2;
-            tempV += 2;
-        }
-
-        inputRGB += pitch_src;
-    }
-
-    return 1;
-}
-
-#define min(a,b) ((a)<(b)?(a):(b))
-#define max(a,b) ((a)>(b)?(a):(b))
-
-static void convert_rgb16_to_yuv422(uint8_t *rgb, uint8_t *yuv, int width, int height)
-{
-    if (!tables_initialized) {
-        initYtab();
-        initCrtab();
-        initCbtab();
-        tables_initialized = 1;
-    }
-
-    uint32_t param[6];
-    param[0] = (uint32_t) width;
-    param[1] = (uint32_t) height;
-    param[2] = (uint32_t) width;
-    param[3] = (uint32_t) height;
-    param[4] = (uint32_t) width;
-    param[5] = (uint32_t) 0;
-
-    uint8_t *table[3];
-    table[0] = gYTable;
-    table[1] = gCbTable + 384;
-    table[2] = gCrTable + 384;
-
-    ccrgb16toyuv_wo_colorkey(rgb, yuv, param, table);
-}
-
-const int FakeCamera::kRed;
-const int FakeCamera::kGreen;
-const int FakeCamera::kBlue;
-
-FakeCamera::FakeCamera(int width, int height)
-          : mTmpRgb16Buffer(0)
-{
-    setSize(width, height);
-}
-
-FakeCamera::~FakeCamera()
-{
-    delete[] mTmpRgb16Buffer;
-}
-
-void FakeCamera::setSize(int width, int height)
-{
-    mWidth = width;
-    mHeight = height;
-    mCounter = 0;
-    mCheckX = 0;
-    mCheckY = 0;
-
-    // This will cause it to be reallocated on the next call
-    // to getNextFrameAsYuv422().
-    delete[] mTmpRgb16Buffer;
-    mTmpRgb16Buffer = 0;
-}
-
-void FakeCamera::getNextFrameAsRgb565(uint16_t *buffer)
-{
-    int size = mWidth / 10;
-
-    drawCheckerboard(buffer, size);
-
-    int x = ((mCounter*3)&255);
-    if(x>128) x = 255 - x;
-    int y = ((mCounter*5)&255);
-    if(y>128) y = 255 - y;
-
-    drawSquare(buffer, x*size/32, y*size/32, (size*5)>>1, (mCounter&0x100)?kRed:kGreen, kBlue);
-
-    mCounter++;
-}
-
-void FakeCamera::getNextFrameAsYuv422(uint8_t *buffer)
-{
-    if (mTmpRgb16Buffer == 0)
-        mTmpRgb16Buffer = new uint16_t[mWidth * mHeight];
-
-    getNextFrameAsRgb565(mTmpRgb16Buffer);
-    convert_rgb16_to_yuv422((uint8_t*)mTmpRgb16Buffer, buffer, mWidth, mHeight);
-}
-
-void FakeCamera::drawSquare(uint16_t *dst, int x, int y, int size, int color, int shadow)
-{
-    int square_xstop, square_ystop, shadow_xstop, shadow_ystop;
-
-    square_xstop = min(mWidth, x+size);
-    square_ystop = min(mHeight, y+size);
-    shadow_xstop = min(mWidth, x+size+(size/4));
-    shadow_ystop = min(mHeight, y+size+(size/4));
-
-    // Do the shadow.
-    uint16_t *sh = &dst[(y+(size/4))*mWidth];
-    for (int j = y + (size/4); j < shadow_ystop; j++) {
-        for (int i = x + (size/4); i < shadow_xstop; i++) {
-            sh[i] &= shadow;
-        }
-        sh += mWidth;
-    }
-
-    // Draw the square.
-    uint16_t *sq = &dst[y*mWidth];
-    for (int j = y; j < square_ystop; j++) {
-        for (int i = x; i < square_xstop; i++) {
-            sq[i] = color;
-        }
-        sq += mWidth;
-    }
-}
-
-void FakeCamera::drawCheckerboard(uint16_t *dst, int size)
-{
-    bool black = true;
-
-    if((mCheckX/size)&1)
-        black = false;
-    if((mCheckY/size)&1)
-        black = !black;
-
-    int county = mCheckY%size;
-    int checkxremainder = mCheckX%size;
-
-    for(int y=0;y<mHeight;y++) {
-        int countx = checkxremainder;
-        bool current = black;
-        for(int x=0;x<mWidth;x++) {
-            dst[y*mWidth+x] = current?0:0xffff;
-            if(countx++ >= size) {
-                countx=0;
-                current = !current;
-            }
-        }
-        if(county++ >= size) {
-            county=0;
-            black = !black;
-        }
-    }
-    mCheckX += 3;
-    mCheckY++;
-}
-
-
-void FakeCamera::dump(int fd) const
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, 255, " width x height (%d x %d), counter (%d), check x-y coordinate(%d, %d)\n", mWidth, mHeight, mCounter, mCheckX, mCheckY);
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-}
-
-
-}; // namespace android
diff --git a/camera/libcameraservice/FakeCamera.h b/camera/libcameraservice/FakeCamera.h
deleted file mode 100644
index f7f8803..0000000
--- a/camera/libcameraservice/FakeCamera.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-**
-** Copyright 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 ANDROID_HARDWARE_FAKECAMERA_H
-#define ANDROID_HARDWARE_FAKECAMERA_H
-
-#include <sys/types.h>
-#include <stdint.h>
-
-namespace android {
-
-/*
- * FakeCamera is used in the CameraHardwareStub to provide a fake video feed
- * when the system does not have a camera in hardware.
- * The fake video is a moving black and white checkerboard background with a
- * bouncing gray square in the foreground.
- * This class is not thread-safe.
- *
- * TODO: Since the major methods provides a raw/uncompressed video feed, rename
- * this class to RawVideoSource.
- */
-
-class FakeCamera {
-public:
-    FakeCamera(int width, int height);
-    ~FakeCamera();
-
-    void setSize(int width, int height);
-    void getNextFrameAsYuv422(uint8_t *buffer);
-    // Write to the fd a string representing the current state.
-    void dump(int fd) const;
-
-private:
-    // TODO: remove the uint16_t buffer param everywhere since it is a field of
-    // this class.
-    void getNextFrameAsRgb565(uint16_t *buffer);
-
-    void drawSquare(uint16_t *buffer, int x, int y, int size, int color, int shadow);
-    void drawCheckerboard(uint16_t *buffer, int size);
-
-    static const int kRed = 0xf800;
-    static const int kGreen = 0x07c0;
-    static const int kBlue = 0x003e;
-
-    int         mWidth, mHeight;
-    int         mCounter;
-    int         mCheckX, mCheckY;
-    uint16_t    *mTmpRgb16Buffer;
-};
-
-}; // namespace android
-
-#endif // ANDROID_HARDWARE_FAKECAMERA_H
diff --git a/camera/tests/CameraServiceTest/Android.mk b/camera/tests/CameraServiceTest/Android.mk
deleted file mode 100644
index 9bb190a..0000000
--- a/camera/tests/CameraServiceTest/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= CameraServiceTest.cpp
-
-LOCAL_MODULE:= CameraServiceTest
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_C_INCLUDES += \
-                frameworks/base/libs
-
-LOCAL_CFLAGS :=
-
-LOCAL_SHARED_LIBRARIES += \
-		libbinder \
-                libcutils \
-                libutils \
-                libui \
-                libcamera_client \
-                libsurfaceflinger_client
-
-include $(BUILD_EXECUTABLE)
diff --git a/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
deleted file mode 100644
index 9fc795b..0000000
--- a/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ /dev/null
@@ -1,849 +0,0 @@
-#define LOG_TAG "CameraServiceTest"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <surfaceflinger/ISurface.h>
-#include <camera/Camera.h>
-#include <camera/CameraParameters.h>
-#include <ui/GraphicBuffer.h>
-#include <camera/ICamera.h>
-#include <camera/ICameraClient.h>
-#include <camera/ICameraService.h>
-#include <ui/Overlay.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-#include <utils/KeyedVector.h>
-#include <utils/Log.h>
-#include <utils/Vector.h>
-#include <utils/threads.h>
-
-using namespace android;
-
-//
-//  Assertion and Logging utilities
-//
-#define INFO(...) \
-    do { \
-        printf(__VA_ARGS__); \
-        printf("\n"); \
-        LOGD(__VA_ARGS__); \
-    } while(0)
-
-void assert_fail(const char *file, int line, const char *func, const char *expr) {
-    INFO("assertion failed at file %s, line %d, function %s:",
-            file, line, func);
-    INFO("%s", expr);
-    exit(1);
-}
-
-void assert_eq_fail(const char *file, int line, const char *func,
-        const char *expr, int actual) {
-    INFO("assertion failed at file %s, line %d, function %s:",
-            file, line, func);
-    INFO("(expected) %s != (actual) %d", expr, actual);
-    exit(1);
-}
-
-#define ASSERT(e) \
-    do { \
-        if (!(e)) \
-            assert_fail(__FILE__, __LINE__, __func__, #e); \
-    } while(0)
-
-#define ASSERT_EQ(expected, actual) \
-    do { \
-        int _x = (actual); \
-        if (_x != (expected)) \
-            assert_eq_fail(__FILE__, __LINE__, __func__, #expected, _x); \
-    } while(0)
-
-//
-//  Holder service for pass objects between processes.
-//
-class IHolder : public IInterface {
-protected:
-    enum {
-        HOLDER_PUT = IBinder::FIRST_CALL_TRANSACTION,
-        HOLDER_GET,
-        HOLDER_CLEAR
-    };
-public:
-    DECLARE_META_INTERFACE(Holder);
-
-    virtual void put(sp<IBinder> obj) = 0;
-    virtual sp<IBinder> get() = 0;
-    virtual void clear() = 0;
-};
-
-class BnHolder : public BnInterface<IHolder> {
-    virtual status_t onTransact(uint32_t code,
-                                const Parcel& data,
-                                Parcel* reply,
-                                uint32_t flags = 0);
-};
-
-class BpHolder : public BpInterface<IHolder> {
-public:
-    BpHolder(const sp<IBinder>& impl)
-        : BpInterface<IHolder>(impl) {
-    }
-
-    virtual void put(sp<IBinder> obj) {
-        Parcel data, reply;
-        data.writeStrongBinder(obj);
-        remote()->transact(HOLDER_PUT, data, &reply, IBinder::FLAG_ONEWAY);
-    }
-
-    virtual sp<IBinder> get() {
-        Parcel data, reply;
-        remote()->transact(HOLDER_GET, data, &reply);
-        return reply.readStrongBinder();
-    }
-
-    virtual void clear() {
-        Parcel data, reply;
-        remote()->transact(HOLDER_CLEAR, data, &reply);
-    }
-};
-
-IMPLEMENT_META_INTERFACE(Holder, "CameraServiceTest.Holder");
-
-status_t BnHolder::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
-    switch(code) {
-        case HOLDER_PUT: {
-            put(data.readStrongBinder());
-            return NO_ERROR;
-        } break;
-        case HOLDER_GET: {
-            reply->writeStrongBinder(get());
-            return NO_ERROR;
-        } break;
-        case HOLDER_CLEAR: {
-            clear();
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-class HolderService : public BnHolder {
-    virtual void put(sp<IBinder> obj) {
-        mObj = obj;
-    }
-    virtual sp<IBinder> get() {
-        return mObj;
-    }
-    virtual void clear() {
-        mObj.clear();
-    }
-private:
-    sp<IBinder> mObj;
-};
-
-//
-//  A mock CameraClient
-//
-class MCameraClient : public BnCameraClient {
-public:
-    virtual void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2);
-    virtual void dataCallback(int32_t msgType, const sp<IMemory>& data);
-    virtual void dataCallbackTimestamp(nsecs_t timestamp,
-            int32_t msgType, const sp<IMemory>& data) {}
-
-    // new functions
-    void clearStat();
-    enum OP { EQ, GE, LE, GT, LT };
-    void assertNotify(int32_t msgType, OP op, int count);
-    void assertData(int32_t msgType, OP op, int count);
-    void waitNotify(int32_t msgType, OP op, int count);
-    void waitData(int32_t msgType, OP op, int count);
-    void assertDataSize(int32_t msgType, OP op, int dataSize);
-
-    void setReleaser(ICamera *releaser) {
-        mReleaser = releaser;
-    }
-private:
-    Mutex mLock;
-    Condition mCond;
-    DefaultKeyedVector<int32_t, int> mNotifyCount;
-    DefaultKeyedVector<int32_t, int> mDataCount;
-    DefaultKeyedVector<int32_t, int> mDataSize;
-    bool test(OP op, int v1, int v2);
-
-    ICamera *mReleaser;
-};
-
-void MCameraClient::clearStat() {
-    Mutex::Autolock _l(mLock);
-    mNotifyCount.clear();
-    mDataCount.clear();
-    mDataSize.clear();
-}
-
-bool MCameraClient::test(OP op, int v1, int v2) {
-    switch (op) {
-        case EQ: return v1 == v2;
-        case GT: return v1 > v2;
-        case LT: return v1 < v2;
-        case GE: return v1 >= v2;
-        case LE: return v1 <= v2;
-        default: ASSERT(0); break;
-    }
-    return false;
-}
-
-void MCameraClient::assertNotify(int32_t msgType, OP op, int count) {
-    Mutex::Autolock _l(mLock);
-    int v = mNotifyCount.valueFor(msgType);
-    ASSERT(test(op, v, count));
-}
-
-void MCameraClient::assertData(int32_t msgType, OP op, int count) {
-    Mutex::Autolock _l(mLock);
-    int v = mDataCount.valueFor(msgType);
-    ASSERT(test(op, v, count));
-}
-
-void MCameraClient::assertDataSize(int32_t msgType, OP op, int dataSize) {
-    Mutex::Autolock _l(mLock);
-    int v = mDataSize.valueFor(msgType);
-    ASSERT(test(op, v, dataSize));
-}
-
-void MCameraClient::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) {
-    INFO(__func__);
-    Mutex::Autolock _l(mLock);
-    ssize_t i = mNotifyCount.indexOfKey(msgType);
-    if (i < 0) {
-        mNotifyCount.add(msgType, 1);
-    } else {
-        ++mNotifyCount.editValueAt(i);
-    }
-    mCond.signal();
-}
-
-void MCameraClient::dataCallback(int32_t msgType, const sp<IMemory>& data) {
-    INFO(__func__);
-    int dataSize = data->size();
-    INFO("data type = %d, size = %d", msgType, dataSize);
-    Mutex::Autolock _l(mLock);
-    ssize_t i = mDataCount.indexOfKey(msgType);
-    if (i < 0) {
-        mDataCount.add(msgType, 1);
-        mDataSize.add(msgType, dataSize);
-    } else {
-        ++mDataCount.editValueAt(i);
-        mDataSize.editValueAt(i) = dataSize;
-    }
-    mCond.signal();
-
-    if (msgType == CAMERA_MSG_VIDEO_FRAME) {
-        ASSERT(mReleaser != NULL);
-        mReleaser->releaseRecordingFrame(data);
-    }
-}
-
-void MCameraClient::waitNotify(int32_t msgType, OP op, int count) {
-    INFO("waitNotify: %d, %d, %d", msgType, op, count);
-    Mutex::Autolock _l(mLock);
-    while (true) {
-        int v = mNotifyCount.valueFor(msgType);
-        if (test(op, v, count)) {
-            break;
-        }
-        mCond.wait(mLock);
-    }
-}
-
-void MCameraClient::waitData(int32_t msgType, OP op, int count) {
-    INFO("waitData: %d, %d, %d", msgType, op, count);
-    Mutex::Autolock _l(mLock);
-    while (true) {
-        int v = mDataCount.valueFor(msgType);
-        if (test(op, v, count)) {
-            break;
-        }
-        mCond.wait(mLock);
-    }
-}
-
-//
-//  A mock Surface
-//
-class MSurface : public BnSurface {
-public:
-    virtual status_t registerBuffers(const BufferHeap& buffers);
-    virtual void postBuffer(ssize_t offset);
-    virtual void unregisterBuffers();
-    virtual sp<OverlayRef> createOverlay(
-            uint32_t w, uint32_t h, int32_t format, int32_t orientation);
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage);
-
-    // new functions
-    void clearStat();
-    void waitUntil(int c0, int c1, int c2);
-
-private:
-    // check callback count
-    Condition mCond;
-    Mutex mLock;
-    int registerBuffersCount;
-    int postBufferCount;
-    int unregisterBuffersCount;
-};
-
-status_t MSurface::registerBuffers(const BufferHeap& buffers) {
-    INFO(__func__);
-    Mutex::Autolock _l(mLock);
-    ++registerBuffersCount;
-    mCond.signal();
-    return NO_ERROR;
-}
-
-void MSurface::postBuffer(ssize_t offset) {
-    // INFO(__func__);
-    Mutex::Autolock _l(mLock);
-    ++postBufferCount;
-    mCond.signal();
-}
-
-void MSurface::unregisterBuffers() {
-    INFO(__func__);
-    Mutex::Autolock _l(mLock);
-    ++unregisterBuffersCount;
-    mCond.signal();
-}
-
-sp<GraphicBuffer> MSurface::requestBuffer(int bufferIdx, int usage) {
-    INFO(__func__);
-    return NULL;
-}
-
-void MSurface::clearStat() {
-    Mutex::Autolock _l(mLock);
-    registerBuffersCount = 0;
-    postBufferCount = 0;
-    unregisterBuffersCount = 0;
-}
-
-void MSurface::waitUntil(int c0, int c1, int c2) {
-    INFO("waitUntil: %d %d %d", c0, c1, c2);
-    Mutex::Autolock _l(mLock);
-    while (true) {
-        if (registerBuffersCount >= c0 &&
-            postBufferCount >= c1 &&
-            unregisterBuffersCount >= c2) {
-            break;
-        }
-        mCond.wait(mLock);
-    }
-}
-
-sp<OverlayRef> MSurface::createOverlay(uint32_t w, uint32_t h, int32_t format,
-        int32_t orientation) {
-    // We don't expect this to be called in current hardware.
-    ASSERT(0);
-    sp<OverlayRef> dummy;
-    return dummy;
-}
-
-//
-//  Utilities to use the Holder service
-//
-sp<IHolder> getHolder() {
-    sp<IServiceManager> sm = defaultServiceManager();
-    ASSERT(sm != 0);
-    sp<IBinder> binder = sm->getService(String16("CameraServiceTest.Holder"));
-    ASSERT(binder != 0);
-    sp<IHolder> holder = interface_cast<IHolder>(binder);
-    ASSERT(holder != 0);
-    return holder;
-}
-
-void putTempObject(sp<IBinder> obj) {
-    INFO(__func__);
-    getHolder()->put(obj);
-}
-
-sp<IBinder> getTempObject() {
-    INFO(__func__);
-    return getHolder()->get();
-}
-
-void clearTempObject() {
-    INFO(__func__);
-    getHolder()->clear();
-}
-
-//
-//  Get a Camera Service
-//
-sp<ICameraService> getCameraService() {
-    sp<IServiceManager> sm = defaultServiceManager();
-    ASSERT(sm != 0);
-    sp<IBinder> binder = sm->getService(String16("media.camera"));
-    ASSERT(binder != 0);
-    sp<ICameraService> cs = interface_cast<ICameraService>(binder);
-    ASSERT(cs != 0);
-    return cs;
-}
-
-//
-// Various Connect Tests
-//
-void testConnect() {
-    INFO(__func__);
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc);
-    ASSERT(c != 0);
-    c->disconnect();
-}
-
-void testAllowConnectOnceOnly() {
-    INFO(__func__);
-    sp<ICameraService> cs = getCameraService();
-    // Connect the first client.
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc);
-    ASSERT(c != 0);
-    // Same client -- ok.
-    ASSERT(cs->connect(cc) != 0);
-    // Different client -- not ok.
-    sp<MCameraClient> cc2 = new MCameraClient();
-    ASSERT(cs->connect(cc2) == 0);
-    c->disconnect();
-}
-
-void testReconnectFailed() {
-    INFO(__func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    sp<MCameraClient> cc2 = new MCameraClient();
-    ASSERT(c->connect(cc2) != NO_ERROR);
-}
-
-void testReconnectSuccess() {
-    INFO(__func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    sp<MCameraClient> cc = new MCameraClient();
-    ASSERT(c->connect(cc) == NO_ERROR);
-}
-
-void testLockFailed() {
-    INFO(__func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    ASSERT(c->lock() != NO_ERROR);
-}
-
-void testLockUnlockSuccess() {
-    INFO(__func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    ASSERT(c->lock() == NO_ERROR);
-    ASSERT(c->unlock() == NO_ERROR);
-}
-
-void testLockSuccess() {
-    INFO(__func__);
-    sp<ICamera> c = interface_cast<ICamera>(getTempObject());
-    ASSERT(c->lock() == NO_ERROR);
-}
-
-//
-// Run the connect tests in another process.
-//
-const char *gExecutable;
-
-struct FunctionTableEntry {
-    const char *name;
-    void (*func)();
-};
-
-FunctionTableEntry function_table[] = {
-#define ENTRY(x) {#x, &x}
-    ENTRY(testReconnectFailed),
-    ENTRY(testReconnectSuccess),
-    ENTRY(testLockUnlockSuccess),
-    ENTRY(testLockFailed),
-    ENTRY(testLockSuccess),
-#undef ENTRY
-};
-
-void runFunction(const char *tag) {
-    INFO("runFunction: %s", tag);
-    int entries = sizeof(function_table) / sizeof(function_table[0]);
-    for (int i = 0; i < entries; i++) {
-        if (strcmp(function_table[i].name, tag) == 0) {
-            (*function_table[i].func)();
-            return;
-        }
-    }
-    ASSERT(0);
-}
-
-void runInAnotherProcess(const char *tag) {
-    pid_t pid = fork();
-    if (pid == 0) {
-        execlp(gExecutable, gExecutable, tag, NULL);
-        ASSERT(0);
-    } else {
-        int status;
-        ASSERT_EQ(pid, wait(&status));
-        ASSERT_EQ(0, status);
-    }
-}
-
-void testReconnect() {
-    INFO(__func__);
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc);
-    ASSERT(c != 0);
-    // Reconnect to the same client -- ok.
-    ASSERT(c->connect(cc) == NO_ERROR);
-    // Reconnect to a different client (but the same pid) -- ok.
-    sp<MCameraClient> cc2 = new MCameraClient();
-    ASSERT(c->connect(cc2) == NO_ERROR);
-    c->disconnect();
-    cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-}
-
-void testLockUnlock() {
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc);
-    ASSERT(c != 0);
-    // We can lock as many times as we want.
-    ASSERT(c->lock() == NO_ERROR);
-    ASSERT(c->lock() == NO_ERROR);
-    // Lock from a different process -- not ok.
-    putTempObject(c->asBinder());
-    runInAnotherProcess("testLockFailed");
-    // Unlock then lock from a different process -- ok.
-    ASSERT(c->unlock() == NO_ERROR);
-    runInAnotherProcess("testLockUnlockSuccess");
-    // Unlock then lock from a different process -- ok.
-    runInAnotherProcess("testLockSuccess");
-    c->disconnect();
-    clearTempObject();
-}
-
-void testReconnectFromAnotherProcess() {
-    INFO(__func__);
-
-    sp<ICameraService> cs = getCameraService();
-    sp<MCameraClient> cc = new MCameraClient();
-    sp<ICamera> c = cs->connect(cc);
-    ASSERT(c != 0);
-    // Reconnect from a different process -- not ok.
-    putTempObject(c->asBinder());
-    runInAnotherProcess("testReconnectFailed");
-    // Unlock then reconnect from a different process -- ok.
-    ASSERT(c->unlock() == NO_ERROR);
-    runInAnotherProcess("testReconnectSuccess");
-    c->disconnect();
-    clearTempObject();
-}
-
-// We need to flush the command buffer after the reference
-// to ICamera is gone. The sleep is for the server to run
-// the destructor for it.
-static void flushCommands() {
-    IPCThreadState::self()->flushCommands();
-    usleep(200000);  // 200ms
-}
-
-// Run a test case
-#define RUN(class_name) do { \
-    { \
-        INFO(#class_name); \
-        class_name instance; \
-        instance.run(); \
-    } \
-    flushCommands(); \
-} while(0)
-
-// Base test case after the the camera is connected.
-class AfterConnect {
-protected:
-    sp<ICameraService> cs;
-    sp<MCameraClient> cc;
-    sp<ICamera> c;
-
-    AfterConnect() {
-        cs = getCameraService();
-        cc = new MCameraClient();
-        c = cs->connect(cc);
-        ASSERT(c != 0);
-    }
-
-    ~AfterConnect() {
-        c.clear();
-        cc.clear();
-        cs.clear();
-    }
-};
-
-class TestSetPreviewDisplay : public AfterConnect {
-public:
-    void run() {
-        sp<MSurface> surface = new MSurface();
-        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestStartPreview : public AfterConnect {
-public:
-    void run() {
-        sp<MSurface> surface = new MSurface();
-        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-
-        ASSERT(c->startPreview() == NO_ERROR);
-        ASSERT(c->previewEnabled() == true);
-
-        surface->waitUntil(1, 10, 0); // needs 1 registerBuffers and 10 postBuffer
-        surface->clearStat();
-
-        c->disconnect();
-        // TODO: CameraService crashes for this. Fix it.
-#if 0
-        sp<MSurface> another_surface = new MSurface();
-        c->setPreviewDisplay(another_surface);  // just to make sure unregisterBuffers
-                                                // is called.
-        surface->waitUntil(0, 0, 1);  // needs unregisterBuffers
-#endif
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestStartPreviewWithoutDisplay : AfterConnect {
-public:
-    void run() {
-        ASSERT(c->startPreview() == NO_ERROR);
-        ASSERT(c->previewEnabled() == true);
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-// Base test case after the the camera is connected and the preview is started.
-class AfterStartPreview : public AfterConnect {
-protected:
-    sp<MSurface> surface;
-
-    AfterStartPreview() {
-        surface = new MSurface();
-        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-        ASSERT(c->startPreview() == NO_ERROR);
-    }
-
-    ~AfterStartPreview() {
-        surface.clear();
-    }
-};
-
-class TestAutoFocus : public AfterStartPreview {
-public:
-    void run() {
-        cc->assertNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 0);
-        c->autoFocus();
-        cc->waitNotify(CAMERA_MSG_FOCUS, MCameraClient::EQ, 1);
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestStopPreview : public AfterStartPreview {
-public:
-    void run() {
-        ASSERT(c->previewEnabled() == true);
-        c->stopPreview();
-        ASSERT(c->previewEnabled() == false);
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestTakePicture: public AfterStartPreview {
-public:
-    void run() {
-        ASSERT(c->takePicture() == NO_ERROR);
-        cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
-        cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
-        cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
-        c->stopPreview();
-#if 1  // TODO: It crashes if we don't have this. Fix it.
-        usleep(100000);
-#endif
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestTakeMultiplePictures: public AfterStartPreview {
-public:
-    void run() {
-        for (int i = 0; i < 10; i++) {
-            cc->clearStat();
-            ASSERT(c->takePicture() == NO_ERROR);
-            cc->waitNotify(CAMERA_MSG_SHUTTER, MCameraClient::EQ, 1);
-            cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
-            cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
-            usleep(100000);  // 100ms
-        }
-        c->disconnect();
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-    }
-};
-
-class TestGetParameters: public AfterStartPreview {
-public:
-    void run() {
-        String8 param_str = c->getParameters();
-        INFO(param_str);
-    }
-};
-
-class TestPictureSize : public AfterStartPreview {
-public:
-    void checkOnePicture(int w, int h) {
-        const float rate = 0.5;  // byte per pixel limit
-        int pixels = w * h;
-
-        CameraParameters param(c->getParameters());
-        param.setPictureSize(w, h);
-        c->setParameters(param.flatten());
-
-        cc->clearStat();
-        ASSERT(c->takePicture() == NO_ERROR);
-        cc->waitData(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, 1);
-        cc->assertDataSize(CAMERA_MSG_RAW_IMAGE, MCameraClient::EQ, pixels*3/2);
-        cc->waitData(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::EQ, 1);
-        cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::LT,
-                int(pixels * rate));
-        cc->assertDataSize(CAMERA_MSG_COMPRESSED_IMAGE, MCameraClient::GT, 0);
-        cc->assertNotify(CAMERA_MSG_ERROR, MCameraClient::EQ, 0);
-        usleep(100000);  // 100ms
-    }
-
-    void run() {
-        checkOnePicture(2048, 1536);
-        checkOnePicture(1600, 1200);
-        checkOnePicture(1024, 768);
-    }
-};
-
-class TestPreviewCallbackFlag : public AfterConnect {
-public:
-    void run() {
-        sp<MSurface> surface = new MSurface();
-        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-
-        // Try all flag combinations.
-        for (int v = 0; v < 8; v++) {
-            cc->clearStat();
-            c->setPreviewCallbackFlag(v);
-            ASSERT(c->previewEnabled() == false);
-            ASSERT(c->startPreview() == NO_ERROR);
-            ASSERT(c->previewEnabled() == true);
-            sleep(2);
-            c->stopPreview();
-            if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) {
-                cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0);
-            } else {
-                if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) {
-                    cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10);
-                } else {
-                    cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1);
-                }
-            }
-        }
-    }
-};
-
-class TestRecording : public AfterConnect {
-public:
-    void run() {
-        ASSERT(c->recordingEnabled() == false);
-        sp<MSurface> surface = new MSurface();
-        ASSERT(c->setPreviewDisplay(surface) == NO_ERROR);
-        c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
-        cc->setReleaser(c.get());
-        c->startRecording();
-        ASSERT(c->recordingEnabled() == true);
-        sleep(2);
-        c->stopRecording();
-        cc->setReleaser(NULL);
-        cc->assertData(CAMERA_MSG_VIDEO_FRAME, MCameraClient::GE, 10);
-    }
-};
-
-class TestPreviewSize : public AfterStartPreview {
-public:
-    void checkOnePicture(int w, int h) {
-        int size = w*h*3/2;  // should read from parameters
-
-        c->stopPreview();
-
-        CameraParameters param(c->getParameters());
-        param.setPreviewSize(w, h);
-        c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK);
-        c->setParameters(param.flatten());
-
-        c->startPreview();
-
-        cc->clearStat();
-        cc->waitData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 1);
-        cc->assertDataSize(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, size);
-    }
-
-    void run() {
-        checkOnePicture(480, 320);
-        checkOnePicture(352, 288);
-        checkOnePicture(176, 144);
-    }
-};
-
-void runHolderService() {
-    defaultServiceManager()->addService(
-            String16("CameraServiceTest.Holder"), new HolderService());
-    ProcessState::self()->startThreadPool();
-}
-
-int main(int argc, char **argv)
-{
-    if (argc != 1) {
-        runFunction(argv[1]);
-        return 0;
-    }
-    INFO("CameraServiceTest start");
-    gExecutable = argv[0];
-    runHolderService();
-
-    testConnect();                              flushCommands();
-    testAllowConnectOnceOnly();                 flushCommands();
-    testReconnect();                            flushCommands();
-    testLockUnlock();                           flushCommands();
-    testReconnectFromAnotherProcess();          flushCommands();
-
-    RUN(TestSetPreviewDisplay);
-    RUN(TestStartPreview);
-    RUN(TestStartPreviewWithoutDisplay);
-    RUN(TestAutoFocus);
-    RUN(TestStopPreview);
-    RUN(TestTakePicture);
-    RUN(TestTakeMultiplePictures);
-    RUN(TestGetParameters);
-    RUN(TestPictureSize);
-    RUN(TestPreviewCallbackFlag);
-    RUN(TestRecording);
-    RUN(TestPreviewSize);
-}
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c
index 60cc521..afa64f8 100644
--- a/cmds/keystore/keystore.c
+++ b/cmds/keystore/keystore.c
@@ -143,15 +143,20 @@
     send(the_socket, message, length, 0);
 }
 
-/* Here is the file format. Values are encrypted by AES CBC, and MD5 is used to
- * compute their checksums. To make the files portable, the length is stored in
- * network order. Note that the first four bytes are reserved for future use and
- * are always set to zero in this implementation. */
+/* Here is the file format. There are two parts in blob.value, the secret and
+ * the description. The secret is stored in ciphertext, and its original size
+ * can be found in blob.length. The description is stored after the secret in
+ * plaintext, and its size is specified in blob.info. The total size of the two
+ * parts must be no more than VALUE_SIZE bytes. The first three bytes of the
+ * file are reserved for future use and are always set to zero. Fields other
+ * than blob.info, blob.length, and blob.value are modified by encrypt_blob()
+ * and decrypt_blob(). Thus they should not be accessed from outside. */
 
 static int the_entropy = -1;
 
 static struct __attribute__((packed)) {
-    uint32_t reserved;
+    uint8_t reserved[3];
+    uint8_t info;
     uint8_t vector[AES_BLOCK_SIZE];
     uint8_t encrypted[0];
     uint8_t digest[MD5_DIGEST_LENGTH];
@@ -166,13 +171,17 @@
     int length;
     int fd;
 
-    if (read(the_entropy, vector, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) {
+    if (read(the_entropy, blob.vector, AES_BLOCK_SIZE) != AES_BLOCK_SIZE) {
         return SYSTEM_ERROR;
     }
 
-    length = blob.length + blob.value - blob.encrypted;
+    length = blob.length + (blob.value - blob.encrypted);
     length = (length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE * AES_BLOCK_SIZE;
 
+    if (blob.info != 0) {
+        memmove(&blob.encrypted[length], &blob.value[blob.length], blob.info);
+    }
+
     blob.length = htonl(blob.length);
     MD5(blob.digested, length - (blob.digested - blob.encrypted), blob.digest);
 
@@ -180,8 +189,8 @@
     AES_cbc_encrypt(blob.encrypted, blob.encrypted, length, aes_key, vector,
                     AES_ENCRYPT);
 
-    blob.reserved = 0;
-    length += blob.encrypted - (uint8_t *)&blob;
+    memset(blob.reserved, 0, sizeof(blob.reserved));
+    length += (blob.encrypted - (uint8_t *)&blob) + blob.info;
 
     fd = open(".tmp", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
     length -= write(fd, &blob, length);
@@ -200,7 +209,7 @@
     length = read(fd, &blob, sizeof(blob));
     close(fd);
 
-    length -= blob.encrypted - (uint8_t *)&blob;
+    length -= (blob.encrypted - (uint8_t *)&blob) + blob.info;
     if (length < blob.value - blob.encrypted || length % AES_BLOCK_SIZE != 0) {
         return VALUE_CORRUPTED;
     }
@@ -215,8 +224,13 @@
 
     length -= blob.value - blob.digested;
     blob.length = ntohl(blob.length);
-    return (blob.length < 0 || blob.length > length) ? VALUE_CORRUPTED :
-           NO_ERROR;
+    if (blob.length < 0 || blob.length > length) {
+        return VALUE_CORRUPTED;
+    }
+    if (blob.info != 0) {
+        memmove(&blob.value[blob.length], &blob.value[length], blob.info);
+    }
+    return NO_ERROR;
 }
 
 /* Here are the actions. Each of them is a function without arguments. All
@@ -266,6 +280,7 @@
     char name[NAME_MAX];
     int n = sprintf(name, "%u_", uid);
     encode_key(&name[n], params[0].value, params[0].length);
+    blob.info = 0;
     blob.length = params[1].length;
     memcpy(blob.value, params[1].value, params[1].length);
     return encrypt_blob(name, &encryption_key);
@@ -336,56 +351,88 @@
 
 #define MASTER_KEY_FILE ".masterkey"
 #define MASTER_KEY_SIZE 16
+#define SALT_SIZE       16
 
-static void generate_key(uint8_t *key, uint8_t *password, int length)
+static void set_key(uint8_t *key, uint8_t *password, int length, uint8_t *salt)
 {
-    PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore",
-                           sizeof("keystore"), 1024, MASTER_KEY_SIZE, key);
+    if (salt) {
+        PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, salt, SALT_SIZE,
+                               8192, MASTER_KEY_SIZE, key);
+    } else {
+        PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore",
+                               sizeof("keystore"), 1024, MASTER_KEY_SIZE, key);
+    }
 }
 
+/* Here is the history. To improve the security, the parameters to generate the
+ * master key has been changed. To make a seamless transition, we update the
+ * file using the same password when the user unlock it for the first time. If
+ * any thing goes wrong during the transition, the new file will not overwrite
+ * the old one. This avoids permanent damages of the existing data. */
+
 static int8_t password()
 {
     uint8_t key[MASTER_KEY_SIZE];
     AES_KEY aes_key;
-    int n;
+    int8_t response = SYSTEM_ERROR;
 
     if (state == UNINITIALIZED) {
-        blob.length = MASTER_KEY_SIZE;
         if (read(the_entropy, blob.value, MASTER_KEY_SIZE) != MASTER_KEY_SIZE) {
            return SYSTEM_ERROR;
         }
     } else {
-        generate_key(key, params[0].value, params[0].length);
+        int fd = open(MASTER_KEY_FILE, O_RDONLY);
+        uint8_t *salt = NULL;
+        if (fd != -1) {
+            int length = read(fd, &blob, sizeof(blob));
+            close(fd);
+            if (length > SALT_SIZE && blob.info == SALT_SIZE) {
+                salt = (uint8_t *)&blob + length - SALT_SIZE;
+            }
+        }
+
+        set_key(key, params[0].value, params[0].length, salt);
         AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key);
-        n = decrypt_blob(MASTER_KEY_FILE, &aes_key);
-        if (n == SYSTEM_ERROR) {
+        response = decrypt_blob(MASTER_KEY_FILE, &aes_key);
+        if (response == SYSTEM_ERROR) {
             return SYSTEM_ERROR;
         }
-        if (n != NO_ERROR || blob.length != MASTER_KEY_SIZE) {
+        if (response != NO_ERROR || blob.length != MASTER_KEY_SIZE) {
             if (retry <= 0) {
                 reset();
                 return UNINITIALIZED;
             }
             return WRONG_PASSWORD + --retry;
         }
+
+        if (!salt && params[1].length == -1) {
+            params[1] = params[0];
+        }
     }
 
     if (params[1].length == -1) {
         memcpy(key, blob.value, MASTER_KEY_SIZE);
     } else {
-        generate_key(key, params[1].value, params[1].length);
+        uint8_t *salt = &blob.value[MASTER_KEY_SIZE];
+        if (read(the_entropy, salt, SALT_SIZE) != SALT_SIZE) {
+            return SYSTEM_ERROR;
+        }
+
+        set_key(key, params[1].value, params[1].length, salt);
         AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key);
         memcpy(key, blob.value, MASTER_KEY_SIZE);
-        n = encrypt_blob(MASTER_KEY_FILE, &aes_key);
+        blob.info = SALT_SIZE;
+        blob.length = MASTER_KEY_SIZE;
+        response = encrypt_blob(MASTER_KEY_FILE, &aes_key);
     }
 
-    if (n == NO_ERROR) {
+    if (response == NO_ERROR) {
         AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &encryption_key);
         AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &decryption_key);
         state = NO_ERROR;
         retry = MAX_RETRY;
     }
-    return n;
+    return response;
 }
 
 static int8_t lock()
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
index 141f69b..4b4923e 100644
--- a/cmds/keystore/keystore_get.h
+++ b/cmds/keystore/keystore_get.h
@@ -32,7 +32,7 @@
 #endif
 
 /* This function is provided for native components to get values from keystore.
- * Users are required to link against libcutils. Keys are values are 8-bit safe.
+ * Users are required to link against libcutils. Keys and values are 8-bit safe.
  * The first two arguments are the key and its length. The third argument
  * specifies the buffer to store the retrieved value, which must be an array of
  * KEYSTORE_MESSAGE_SIZE bytes. This function returns the length of the value or
@@ -65,7 +65,10 @@
             }
             offset += n;
         }
+    } else {
+        length = -1;
     }
+
     close(sock);
     return length;
 }
diff --git a/cmds/surfaceflinger/Android.mk b/cmds/surfaceflinger/Android.mk
index bfa58a1..1df32bb 100644
--- a/cmds/surfaceflinger/Android.mk
+++ b/cmds/surfaceflinger/Android.mk
@@ -10,7 +10,7 @@
 	libutils
 
 LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/../../libs/surfaceflinger
+	$(LOCAL_PATH)/../../services/surfaceflinger
 
 LOCAL_MODULE:= surfaceflinger
 
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/IInterface.h b/include/binder/IInterface.h
index 273d922..5f9f69c 100644
--- a/include/binder/IInterface.h
+++ b/include/binder/IInterface.h
@@ -72,21 +72,24 @@
 // ----------------------------------------------------------------------
 
 #define DECLARE_META_INTERFACE(INTERFACE)                               \
-    static const String16 descriptor;                                   \
-    static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        \
-    virtual const String16& getInterfaceDescriptor() const;             \
+    static const android::String16 descriptor;                          \
+    static android::sp<I##INTERFACE> asInterface(                       \
+            const android::sp<android::IBinder>& obj);                  \
+    virtual const android::String16& getInterfaceDescriptor() const;    \
     I##INTERFACE();                                                     \
     virtual ~I##INTERFACE();                                            \
 
 
 #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
-    const String16 I##INTERFACE::descriptor(NAME);                      \
-    const String16& I##INTERFACE::getInterfaceDescriptor() const {      \
+    const android::String16 I##INTERFACE::descriptor(NAME);             \
+    const android::String16&                                            \
+            I##INTERFACE::getInterfaceDescriptor() const {              \
         return I##INTERFACE::descriptor;                                \
     }                                                                   \
-    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \
+    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
+            const android::sp<android::IBinder>& obj)                   \
     {                                                                   \
-        sp<I##INTERFACE> intr;                                          \
+        android::sp<I##INTERFACE> intr;                                 \
         if (obj != NULL) {                                              \
             intr = static_cast<I##INTERFACE*>(                          \
                 obj->queryLocalInterface(                               \
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..97dd391
--- /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 Looper;
+
+// ----------------------------------------------------------------------------
+
+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<Looper> getLooper() const;
+    sp<ISensorEventConnection> mSensorEventConnection;
+    sp<SensorChannel> mSensorChannel;
+    mutable Mutex mLock;
+    mutable sp<Looper> mLooper;
+};
+
+// ----------------------------------------------------------------------------
+}; // 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..d6ae5e9 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,26 @@
 
     // 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)
     Statistics  stats;
-    FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
+    int8_t      headBuf;        // last retired buffer
+    uint8_t     reservedBytes[3];
+    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 +139,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 +147,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 +166,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);
@@ -235,24 +202,39 @@
     status_t undoDequeue(int buf);
     
     status_t lock(int buf);
+    status_t cancel(int buf);
     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 UndoDequeueUpdate : public UpdateBase {
-        inline UndoDequeueUpdate(SharedBufferBase* sbb);
+    struct DequeueUpdate : public UpdateBase {
+        inline DequeueUpdate(SharedBufferBase* sbb);
+        inline ssize_t operator()();
+    };
+
+    struct CancelUpdate : public UpdateBase {
+        int tail, buf;
+        inline CancelUpdate(SharedBufferBase* sbb, int tail, int buf);
         inline ssize_t operator()();
     };
 
@@ -260,25 +242,33 @@
 
     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 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 +277,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 +363,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 +386,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..da4d56f 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 {
 // ----------------------------------------------------------------------------
@@ -77,6 +77,11 @@
         eOrientationSwapMask    = 0x01
     };
     
+    enum {
+        eElectronBeamAnimationOn  = 0x01,
+        eElectronBeamAnimationOff = 0x10
+    };
+
     // flags for setOrientation
     enum {
         eOrientationAnimationDisable = 0x00000001
@@ -85,8 +90,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;
@@ -107,6 +115,17 @@
      */
     virtual void bootFinished() = 0;
 
+    /* Capture the specified screen. requires READ_FRAME_BUFFER permission
+     * This function will fail if there is a secure window on screen.
+     */
+    virtual status_t captureScreen(DisplayID dpy,
+            sp<IMemoryHeap>* heap,
+            uint32_t* width, uint32_t* height, PixelFormat* format,
+            uint32_t reqWidth, uint32_t reqHeight) = 0;
+
+    virtual status_t turnElectronBeamOff(int32_t mode) = 0;
+    virtual status_t turnElectronBeamOn(int32_t mode) = 0;
+
     /* Signal surfaceflinger that there might be some work to do
      * This is an ASYNCHRONOUS call.
      */
@@ -123,13 +142,17 @@
         // Java by ActivityManagerService.
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
+        CREATE_CLIENT_CONNECTION,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
         CLOSE_GLOBAL_TRANSACTION,
         SET_ORIENTATION,
         FREEZE_DISPLAY,
         UNFREEZE_DISPLAY,
-        SIGNAL
+        SIGNAL,
+        CAPTURE_SCREEN,
+        TURN_ELECTRON_BEAM_OFF,
+        TURN_ELECTRON_BEAM_ON
     };
 
     virtual status_t    onTransact( uint32_t code,
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..22684db 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,89 +166,137 @@
     // 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 cancelBuffer(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);
     int queueBuffer(android_native_buffer_t* buffer);
+    int cancelBuffer(android_native_buffer_t* buffer);
     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 +305,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..a80832d 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,56 @@
     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;
 };
 
+// ---------------------------------------------------------------------------
+
+class ScreenshotClient
+{
+    sp<IMemoryHeap> mHeap;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    PixelFormat mFormat;
+public:
+    ScreenshotClient();
+
+    // frees the previous screenshot and capture a new one
+    status_t update();
+    status_t update(uint32_t reqWidth, uint32_t reqHeight);
+
+    // release memory occupied by the screenshot
+    void release();
+
+    // pixels are valid until this object is freed or
+    // release() or update() is called
+    void const* getPixels() const;
+
+    uint32_t getWidth() const;
+    uint32_t getHeight() const;
+    PixelFormat getFormat() const;
+    uint32_t getStride() const;
+    // size of allocated memory in bytes
+    size_t getSize() const;
+};
+
+// ---------------------------------------------------------------------------
 }; // namespace android
 
 #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3b18c77..d78e35f 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,78 +60,176 @@
 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 (implies keyboard, has DPAD keys). */
+    INPUT_DEVICE_CLASS_DPAD          = 0x00000020,
+
+    /* The input device is a gamepad (implies keyboard, has BUTTON keys). */
+    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.
+    // Synthetic raw event type codes produced when devices are added or removed.
     enum {
-        CLASS_KEYBOARD      = 0x00000001,
-        CLASS_ALPHAKEY      = 0x00000002,
-        CLASS_TOUCHSCREEN   = 0x00000004,
-        CLASS_TRACKBALL     = 0x00000008,
-        CLASS_TOUCHSCREEN_MT= 0x00000010,
-        CLASS_DPAD          = 0x00000020
+        // Sent when a device is added.
+        DEVICE_ADDED = 0x10000000,
+        // Sent when a device is removed.
+        DEVICE_REMOVED = 0x20000000,
+        // Sent when all added/removed devices from the most recent scan have been reported.
+        // This event is always sent at least once.
+        FINISHED_DEVICE_SCAN = 0x30000000,
     };
-    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;
+
+    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
-    void addExcludedDevice(const char* deviceName);
+    virtual void addExcludedDevice(const char* deviceName) = 0;
 
-    // special type codes when devices are added/removed.
-    enum {
-        DEVICE_ADDED = 0x10000000,
-        DEVICE_REMOVED = 0x20000000
-    };
+    /*
+     * 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;
+
+    virtual void dump(String8& dump) = 0;
+};
+
+class EventHub : public EventHubInterface
+{
+public:
+    EventHub();
+
+    status_t errorCheck() const;
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
     
-    // examine key input devices for specific framework keycode support
-    bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags);
+    virtual String8 getDeviceName(int32_t deviceId) const;
+    
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const;
 
-    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 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);
+
+    virtual void dump(String8& dump);
 
 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);
-    int scan_dir(const char *dirname);
-    int read_notify(int nfd);
+    int openDevice(const char *device);
+    int closeDevice(const char *device);
+    int scanDir(const char *dirname);
+    int readNotify(int nfd);
 
     status_t mError;
 
@@ -117,15 +241,22 @@
         uint8_t*        keyBitmask;
         KeyLayoutMap*   layoutMap;
         String8         keylayoutFilename;
+        int             fd;
         device_t*       next;
         
         device_t(int32_t _id, const char* _path, const char* name);
         ~device_t();
     };
 
-    device_t* getDevice(int32_t deviceId) const;
-    bool hasKeycode(device_t* device, int keycode) const;
+    device_t* getDeviceLocked(int32_t deviceId) const;
+    bool hasKeycodeLocked(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;
     
@@ -147,12 +278,19 @@
     int             mFDCount;
 
     bool            mOpened;
+    bool            mNeedToSendFinishedDeviceScan;
     List<String8>   mExcludedDevices;
 
     // 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..c913355 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> >
 {
@@ -56,15 +56,18 @@
     status_t setUpdateRectangle(const Rect& updateRect);
     status_t compositionComplete();
     
+    // for debugging only
+    int getCurrentBufferIndex() const;
+
 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;
@@ -77,6 +80,7 @@
     int32_t mNumBuffers;
     int32_t mNumFreeBuffers;
     int32_t mBufferHead;
+    int32_t mCurrentBufferIndex;
     bool mUpdateOnDemand;
 };
     
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/GraphicLog.h b/include/ui/GraphicLog.h
new file mode 100644
index 0000000..ee1b09a
--- /dev/null
+++ b/include/ui/GraphicLog.h
@@ -0,0 +1,70 @@
+/*
+ * 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_GRAPHIC_LOG_H
+#define _UI_GRAPHIC_LOG_H
+
+#include <utils/Singleton.h>
+#include <cutils/compiler.h>
+
+namespace android {
+
+class GraphicLog : public Singleton<GraphicLog>
+{
+    int32_t mEnabled;
+    static void logImpl(int32_t tag, int32_t buffer);
+    static void logImpl(int32_t tag, int32_t identity, int32_t buffer);
+
+public:
+    enum {
+        SF_APP_DEQUEUE_BEFORE   = 60100,
+        SF_APP_DEQUEUE_AFTER    = 60101,
+        SF_APP_LOCK_BEFORE      = 60102,
+        SF_APP_LOCK_AFTER       = 60103,
+        SF_APP_QUEUE            = 60104,
+
+        SF_REPAINT              = 60105,
+        SF_COMPOSITION_COMPLETE = 60106,
+        SF_UNLOCK_CLIENTS       = 60107,
+        SF_SWAP_BUFFERS         = 60108,
+        SF_REPAINT_DONE         = 60109,
+
+        SF_FB_POST_BEFORE       = 60110,
+        SF_FB_POST_AFTER        = 60111,
+        SF_FB_DEQUEUE_BEFORE    = 60112,
+        SF_FB_DEQUEUE_AFTER     = 60113,
+        SF_FB_LOCK_BEFORE       = 60114,
+        SF_FB_LOCK_AFTER        = 60115,
+    };
+
+    inline void log(int32_t tag, int32_t buffer) {
+        if (CC_UNLIKELY(mEnabled))
+            logImpl(tag, buffer);
+    }
+    inline void log(int32_t tag, int32_t identity, int32_t buffer) {
+        if (CC_UNLIKELY(mEnabled))
+            logImpl(tag, identity, buffer);
+    }
+
+    GraphicLog();
+
+    void setEnabled(bool enable);
+};
+
+}
+
+#endif // _UI_GRAPHIC_LOG_H
+
diff --git a/include/ui/Input.h b/include/ui/Input.h
new file mode 100644
index 0000000..8c6018b
--- /dev/null
+++ b/include/ui/Input.h
@@ -0,0 +1,502 @@
+/*
+ * 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.
+ * Smallest number of pointers is 1.
+ */
+#define MAX_POINTERS 10
+
+/*
+ * Maximum pointer id value supported in a motion event.
+ * Smallest pointer id is 0.
+ * (This is limited by our use of BitSet32 to track pointer assignments.)
+ */
+#define MAX_POINTER_ID 31
+
+/*
+ * 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.
+ *
+ * These flags are also defined in frameworks/base/core/java/android/view/WindowManagerPolicy.java.
+ */
+enum {
+    /* These flags originate in RawEvents and are generally set in the key map.
+     * See also labels for policy flags in KeycodeLabels.h. */
+
+    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_VIRTUAL = 0x00000100,
+
+    POLICY_FLAG_RAW_MASK = 0x0000ffff,
+
+    /* These flags are set by the input dispatcher. */
+
+    // Indicates that the input event was injected.
+    POLICY_FLAG_INJECTED = 0x01000000,
+
+    // Indicates that the input event is from a trusted source such as a directly attached
+    // input device or an application with system-wide event injection permission.
+    POLICY_FLAG_TRUSTED = 0x02000000,
+
+    /* 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,
+
+    // Indicates that the event should be dispatched to applications.
+    // The input event should still be sent to the InputDispatcher so that it can see all
+    // input events received include those that it will not deliver.
+    POLICY_FLAG_PASS_TO_USER = 0x40000000,
+};
+
+/*
+ * 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..5f77cba
--- /dev/null
+++ b/include/ui/InputDispatcher.h
@@ -0,0 +1,1083 @@
+/*
+ * 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/Looper.h>
+#include <utils/Pool.h>
+#include <utils/BitSet.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <limits.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 the event is being delivered to a foreground application. */
+        FLAG_FOREGROUND = 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 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 = 0x04,
+
+        /* This flag indicates that a motion event is being split across multiple windows. */
+        FLAG_SPLIT = 0x08,
+    };
+
+    // The input channel to be targeted.
+    sp<InputChannel> inputChannel;
+
+    // Flags for the input target.
+    int32_t flags;
+
+    // The x and y offset to add to a MotionEvent as it is delivered.
+    // (ignored for KeyEvents)
+    float xOffset, yOffset;
+
+    // The subset of pointer ids to include in motion events dispatched to this input target
+    // if FLAG_SPLIT is set.
+    BitSet32 pointerIds;
+};
+
+
+/*
+ * An input window describes the bounds of a window that can receive input.
+ */
+struct InputWindow {
+    // Window flags from WindowManager.LayoutParams
+    enum {
+        FLAG_ALLOW_LOCK_WHILE_SCREEN_ON     = 0x00000001,
+        FLAG_DIM_BEHIND        = 0x00000002,
+        FLAG_BLUR_BEHIND        = 0x00000004,
+        FLAG_NOT_FOCUSABLE      = 0x00000008,
+        FLAG_NOT_TOUCHABLE      = 0x00000010,
+        FLAG_NOT_TOUCH_MODAL    = 0x00000020,
+        FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040,
+        FLAG_KEEP_SCREEN_ON     = 0x00000080,
+        FLAG_LAYOUT_IN_SCREEN   = 0x00000100,
+        FLAG_LAYOUT_NO_LIMITS   = 0x00000200,
+        FLAG_FULLSCREEN      = 0x00000400,
+        FLAG_FORCE_NOT_FULLSCREEN   = 0x00000800,
+        FLAG_DITHER             = 0x00001000,
+        FLAG_SECURE             = 0x00002000,
+        FLAG_SCALED             = 0x00004000,
+        FLAG_IGNORE_CHEEK_PRESSES    = 0x00008000,
+        FLAG_LAYOUT_INSET_DECOR = 0x00010000,
+        FLAG_ALT_FOCUSABLE_IM = 0x00020000,
+        FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000,
+        FLAG_SHOW_WHEN_LOCKED = 0x00080000,
+        FLAG_SHOW_WALLPAPER = 0x00100000,
+        FLAG_TURN_SCREEN_ON = 0x00200000,
+        FLAG_DISMISS_KEYGUARD = 0x00400000,
+        FLAG_SPLIT_TOUCH = 0x00800000,
+        FLAG_KEEP_SURFACE_WHILE_ANIMATING = 0x10000000,
+        FLAG_COMPATIBLE_WINDOW = 0x20000000,
+        FLAG_SYSTEM_ERROR = 0x40000000,
+    };
+
+    // Window types from WindowManager.LayoutParams
+    enum {
+        FIRST_APPLICATION_WINDOW = 1,
+        TYPE_BASE_APPLICATION   = 1,
+        TYPE_APPLICATION        = 2,
+        TYPE_APPLICATION_STARTING = 3,
+        LAST_APPLICATION_WINDOW = 99,
+        FIRST_SUB_WINDOW        = 1000,
+        TYPE_APPLICATION_PANEL  = FIRST_SUB_WINDOW,
+        TYPE_APPLICATION_MEDIA  = FIRST_SUB_WINDOW+1,
+        TYPE_APPLICATION_SUB_PANEL = FIRST_SUB_WINDOW+2,
+        TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3,
+        TYPE_APPLICATION_MEDIA_OVERLAY  = FIRST_SUB_WINDOW+4,
+        LAST_SUB_WINDOW         = 1999,
+        FIRST_SYSTEM_WINDOW     = 2000,
+        TYPE_STATUS_BAR         = FIRST_SYSTEM_WINDOW,
+        TYPE_SEARCH_BAR         = FIRST_SYSTEM_WINDOW+1,
+        TYPE_PHONE              = FIRST_SYSTEM_WINDOW+2,
+        TYPE_SYSTEM_ALERT       = FIRST_SYSTEM_WINDOW+3,
+        TYPE_KEYGUARD           = FIRST_SYSTEM_WINDOW+4,
+        TYPE_TOAST              = FIRST_SYSTEM_WINDOW+5,
+        TYPE_SYSTEM_OVERLAY     = FIRST_SYSTEM_WINDOW+6,
+        TYPE_PRIORITY_PHONE     = FIRST_SYSTEM_WINDOW+7,
+        TYPE_SYSTEM_DIALOG      = FIRST_SYSTEM_WINDOW+8,
+        TYPE_KEYGUARD_DIALOG    = FIRST_SYSTEM_WINDOW+9,
+        TYPE_SYSTEM_ERROR       = FIRST_SYSTEM_WINDOW+10,
+        TYPE_INPUT_METHOD       = FIRST_SYSTEM_WINDOW+11,
+        TYPE_INPUT_METHOD_DIALOG= FIRST_SYSTEM_WINDOW+12,
+        TYPE_WALLPAPER          = FIRST_SYSTEM_WINDOW+13,
+        TYPE_STATUS_BAR_PANEL   = FIRST_SYSTEM_WINDOW+14,
+        TYPE_SECURE_SYSTEM_OVERLAY = FIRST_SYSTEM_WINDOW+15,
+        LAST_SYSTEM_WINDOW      = 2999,
+    };
+
+    sp<InputChannel> inputChannel;
+    String8 name;
+    int32_t layoutParamsFlags;
+    int32_t layoutParamsType;
+    nsecs_t dispatchingTimeout;
+    int32_t frameLeft;
+    int32_t frameTop;
+    int32_t frameRight;
+    int32_t frameBottom;
+    int32_t visibleFrameLeft;
+    int32_t visibleFrameTop;
+    int32_t visibleFrameRight;
+    int32_t visibleFrameBottom;
+    int32_t touchableAreaLeft;
+    int32_t touchableAreaTop;
+    int32_t touchableAreaRight;
+    int32_t touchableAreaBottom;
+    bool visible;
+    bool canReceiveKeys;
+    bool hasFocus;
+    bool hasWallpaper;
+    bool paused;
+    int32_t layer;
+    int32_t ownerPid;
+    int32_t ownerUid;
+
+    bool touchableAreaContainsPoint(int32_t x, int32_t y) const;
+    bool frameContainsPoint(int32_t x, int32_t y) const;
+
+    /* Returns true if the window is of a trusted type that is allowed to silently
+     * overlay other windows for the purpose of implementing the secure views feature.
+     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
+     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
+     */
+    bool isTrustedOverlay() const;
+};
+
+
+/*
+ * A private handle type used by the input manager to track the window.
+ */
+class InputApplicationHandle : public RefBase {
+protected:
+    InputApplicationHandle() { }
+    virtual ~InputApplicationHandle() { }
+};
+
+
+/*
+ * An input application describes properties of an application that can receive input.
+ */
+struct InputApplication {
+    String8 name;
+    nsecs_t dispatchingTimeout;
+    sp<InputApplicationHandle> handle;
+};
+
+
+/*
+ * 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 application is not responding.
+     * Returns a new timeout to continue waiting, or 0 to abort dispatch. */
+    virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
+            const sp<InputChannel>& inputChannel) = 0;
+
+    /* Notifies the system that an input channel is unrecoverably broken. */
+    virtual void notifyInputChannelBroken(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;
+
+    /* 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;
+
+    /* Intercepts a key event immediately before queueing it.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
+     * should be dispatched to applications.
+     */
+    virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
+            int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
+            uint32_t& policyFlags) = 0;
+
+    /* Intercepts a generic touch, trackball or other event before queueing it.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * This method is expected to set the POLICY_FLAG_PASS_TO_USER policy flag if the event
+     * should be dispatched to applications.
+     */
+    virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) = 0;
+
+    /* Allows the policy a chance to intercept a key before dispatching. */
+    virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
+            const KeyEvent* keyEvent, uint32_t policyFlags) = 0;
+
+    /* Notifies the policy about switch events.
+     */
+    virtual void notifySwitch(nsecs_t when,
+            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 0;
+
+    /* Poke user activity for an event dispatched to a window. */
+    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) = 0;
+
+    /* Checks whether a given application pid/uid has permission to inject input events
+     * into other applications.
+     *
+     * This method is special in that its implementation promises to be non-reentrant and
+     * is safe to call while holding other locks.  (Most other methods make no such guarantees!)
+     */
+    virtual bool checkInjectEventsPermissionNonReentrant(
+            int32_t injectorPid, int32_t injectorUid) = 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:
+    /* Dumps the state of the input dispatcher.
+     *
+     * This method may be called on any thread (usually by the input manager). */
+    virtual void dump(String8& dump) = 0;
+
+    /* 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 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;
+    virtual void notifySwitch(nsecs_t when,
+            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) = 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;
+
+    /* Sets the list of input windows.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void setInputWindows(const Vector<InputWindow>& inputWindows) = 0;
+
+    /* Sets the focused application.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void setFocusedApplication(const InputApplication* inputApplication) = 0;
+
+    /* Sets the input dispatching mode.
+     *
+     * This method may be called on any thread (usually by the input manager).
+     */
+    virtual void setInputDispatchMode(bool enabled, bool frozen) = 0;
+
+    /* Registers or unregister input channels that may be used as targets for input events.
+     * If monitor is true, the channel will receive a copy of all input events.
+     *
+     * These methods may be called on any thread (usually by the input manager).
+     */
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) = 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 dump(String8& dump);
+
+    virtual void dispatchOnce();
+
+    virtual void notifyConfigurationChanged(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 void notifySwitch(nsecs_t when,
+            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) ;
+
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis);
+
+    virtual void setInputWindows(const Vector<InputWindow>& inputWindows);
+    virtual void setFocusedApplication(const InputApplication* inputApplication);
+    virtual void setInputDispatchMode(bool enabled, bool frozen);
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor);
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel);
+
+private:
+    template <typename T>
+    struct Link {
+        T* next;
+        T* prev;
+    };
+
+    struct InjectionState {
+        mutable int32_t refCount;
+
+        int32_t injectorPid;
+        int32_t injectorUid;
+        int32_t injectionResult;  // initially INPUT_EVENT_INJECTION_PENDING
+        bool injectionIsAsync; // set to true if injection is not waiting for the result
+        int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
+    };
+
+    struct EventEntry : Link<EventEntry> {
+        enum {
+            TYPE_SENTINEL,
+            TYPE_CONFIGURATION_CHANGED,
+            TYPE_KEY,
+            TYPE_MOTION
+        };
+
+        mutable int32_t refCount;
+        int32_t type;
+        nsecs_t eventTime;
+        uint32_t policyFlags;
+        InjectionState* injectionState;
+
+        bool dispatchInProgress; // initially false, set to true while dispatching
+
+        inline bool isInjected() { return injectionState != NULL; }
+    };
+
+    struct ConfigurationChangedEntry : EventEntry {
+    };
+
+    struct KeyEntry : EventEntry {
+        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;
+
+        bool syntheticRepeat; // set to true for synthetic key repeats
+
+        enum InterceptKeyResult {
+            INTERCEPT_KEY_RESULT_UNKNOWN,
+            INTERCEPT_KEY_RESULT_SKIP,
+            INTERCEPT_KEY_RESULT_CONTINUE,
+        };
+        InterceptKeyResult interceptKeyResult; // set based on the interception result
+    };
+
+    struct MotionSample {
+        MotionSample* next;
+
+        nsecs_t eventTime;
+        PointerCoords pointerCoords[MAX_POINTERS];
+    };
+
+    struct MotionEntry : EventEntry {
+        int32_t deviceId;
+        int32_t source;
+        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;
+
+        // 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 hasForegroundTarget() const {
+            return targetFlags & InputTarget::FLAG_FOREGROUND;
+        }
+
+        inline bool isSplit() const {
+            return targetFlags & InputTarget::FLAG_SPLIT;
+        }
+    };
+
+    // 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;
+        nsecs_t eventTime;
+        KeyEntry* keyEntry;
+        sp<InputChannel> inputChannel;
+        sp<InputApplicationHandle> inputApplicationHandle;
+        int32_t userActivityEventType;
+    };
+
+    // Generic queue implementation.
+    template <typename T>
+    struct Queue {
+        T headSentinel;
+        T tailSentinel;
+
+        inline Queue() {
+            headSentinel.prev = NULL;
+            headSentinel.next = & tailSentinel;
+            tailSentinel.prev = & headSentinel;
+            tailSentinel.next = NULL;
+        }
+
+        inline bool isEmpty() const {
+            return headSentinel.next == & tailSentinel;
+        }
+
+        inline void enqueueAtTail(T* entry) {
+            T* last = tailSentinel.prev;
+            last->next = entry;
+            entry->prev = last;
+            entry->next = & tailSentinel;
+            tailSentinel.prev = entry;
+        }
+
+        inline void enqueueAtHead(T* entry) {
+            T* first = headSentinel.next;
+            headSentinel.next = entry;
+            entry->prev = & headSentinel;
+            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 = headSentinel.next;
+            dequeue(first);
+            return first;
+        }
+
+        uint32_t count() const;
+    };
+
+    /* Allocates queue entries and performs reference counting as needed. */
+    class Allocator {
+    public:
+        Allocator();
+
+        InjectionState* obtainInjectionState(int32_t injectorPid, int32_t injectorUid);
+        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,
+                int32_t targetFlags, float xOffset, float yOffset);
+        CommandEntry* obtainCommandEntry(Command command);
+
+        void releaseInjectionState(InjectionState* injectionState);
+        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 recycleKeyEntry(KeyEntry* entry);
+
+        void appendMotionSample(MotionEntry* motionEntry,
+                nsecs_t eventTime, const PointerCoords* pointerCoords);
+
+    private:
+        Pool<InjectionState> mInjectionStatePool;
+        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,
+                uint32_t policyFlags);
+        void releaseEventEntryInjectionState(EventEntry* entry);
+    };
+
+    /* Tracks dispatched key and motion event state so that cancelation events can be
+     * synthesized when events are dropped. */
+    class InputState {
+    public:
+        // Specifies whether a given event will violate input state consistency.
+        enum Consistency {
+            // The event is consistent with the current input state.
+            CONSISTENT,
+            // The event is inconsistent with the current input state but applications
+            // will tolerate it.  eg. Down followed by another down.
+            TOLERABLE,
+            // The event is inconsistent with the current input state and will probably
+            // cause applications to crash.  eg. Up without prior down, move with
+            // unexpected number of pointers.
+            BROKEN
+        };
+
+        // Specifies the sources to cancel.
+        enum CancelationOptions {
+            CANCEL_ALL_EVENTS = 0,
+            CANCEL_POINTER_EVENTS = 1,
+            CANCEL_NON_POINTER_EVENTS = 2,
+        };
+
+        InputState();
+        ~InputState();
+
+        // Returns true if there is no state to be canceled.
+        bool isNeutral() const;
+
+        // Records tracking information for an event that has just been published.
+        // Returns whether the event is consistent with the current input state.
+        Consistency trackEvent(const EventEntry* entry);
+
+        // Records tracking information for a key event that has just been published.
+        // Returns whether the event is consistent with the current input state.
+        Consistency trackKey(const KeyEntry* entry);
+
+        // Records tracking information for a motion event that has just been published.
+        // Returns whether the event is consistent with the current input state.
+        Consistency trackMotion(const MotionEntry* entry);
+
+        // Synthesizes cancelation events for the current state and resets the tracked state.
+        void synthesizeCancelationEvents(nsecs_t currentTime, Allocator* allocator,
+                Vector<EventEntry*>& outEvents, CancelationOptions options);
+
+        // Clears the current state.
+        void clear();
+
+    private:
+        struct KeyMemento {
+            int32_t deviceId;
+            int32_t source;
+            int32_t keyCode;
+            int32_t scanCode;
+            nsecs_t downTime;
+        };
+
+        struct MotionMemento {
+            int32_t deviceId;
+            int32_t source;
+            float xPrecision;
+            float yPrecision;
+            nsecs_t downTime;
+            uint32_t pointerCount;
+            int32_t pointerIds[MAX_POINTERS];
+            PointerCoords pointerCoords[MAX_POINTERS];
+
+            void setPointers(const MotionEntry* entry);
+        };
+
+        Vector<KeyMemento> mKeyMementos;
+        Vector<MotionMemento> mMotionMementos;
+
+        static bool shouldCancelEvent(int32_t eventSource, CancelationOptions options);
+    };
+
+    /* 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 input channel has been unregistered.
+            STATUS_ZOMBIE
+        };
+
+        Status status;
+        sp<InputChannel> inputChannel;
+        InputPublisher inputPublisher;
+        InputState inputState;
+        Queue<DispatchEntry> outboundQueue;
+
+        nsecs_t lastEventTime; // the time when the event was originally captured
+        nsecs_t lastDispatchTime; // the time when the last event was dispatched
+
+        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;
+
+        // Gets the time since the current event was originally obtained from the input driver.
+        inline double getEventLatencyMillis(nsecs_t currentTime) const {
+            return (currentTime - lastEventTime) / 1000000.0;
+        }
+
+        // Gets the time since the current event entered the outbound dispatch queue.
+        inline double getDispatchLatencyMillis(nsecs_t currentTime) const {
+            return (currentTime - lastDispatchTime) / 1000000.0;
+        }
+
+        status_t initialize();
+    };
+
+    enum DropReason {
+        DROP_REASON_NOT_DROPPED = 0,
+        DROP_REASON_POLICY = 1,
+        DROP_REASON_APP_SWITCH = 2,
+        DROP_REASON_DISABLED = 3,
+    };
+
+    sp<InputDispatcherPolicyInterface> mPolicy;
+
+    Mutex mLock;
+
+    Allocator mAllocator;
+    sp<Looper> mLooper;
+
+    EventEntry* mPendingEvent;
+    Queue<EventEntry> mInboundQueue;
+    Queue<CommandEntry> mCommandQueue;
+
+    Vector<EventEntry*> mTempCancelationEvents;
+
+    void dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout, nsecs_t keyRepeatDelay,
+            nsecs_t* nextWakeupTime);
+
+    // Enqueues an inbound event.  Returns true if mLooper->wake() should be called.
+    bool enqueueInboundEventLocked(EventEntry* entry);
+
+    // Cleans up input state when dropping an inbound event.
+    void dropInboundEventLocked(EventEntry* entry, DropReason dropReason);
+
+    // App switch latency optimization.
+    bool mAppSwitchSawKeyDown;
+    nsecs_t mAppSwitchDueTime;
+
+    static bool isAppSwitchKeyCode(int32_t keyCode);
+    bool isAppSwitchKeyEventLocked(KeyEntry* keyEntry);
+    bool isAppSwitchPendingLocked();
+    void resetPendingAppSwitchLocked(bool handled);
+
+    // All registered connections mapped by receive pipe file descriptor.
+    KeyedVector<int, sp<Connection> > mConnectionsByReceiveFd;
+
+    ssize_t getConnectionIndexLocked(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;
+
+    // Input channels that will receive a copy of all input events.
+    Vector<sp<InputChannel> > mMonitoringChannels;
+
+    // Preallocated key event object used for policy inquiries.
+    KeyEvent mReusableKeyEvent;
+
+    // Event injection and synchronization.
+    Condition mInjectionResultAvailableCondition;
+    bool hasInjectionPermission(int32_t injectorPid, int32_t injectorUid);
+    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
+
+    Condition mInjectionSyncFinishedCondition;
+    void incrementPendingForegroundDispatchesLocked(EventEntry* entry);
+    void decrementPendingForegroundDispatchesLocked(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.
+    struct KeyRepeatState {
+        KeyEntry* lastKeyEntry; // or null if no repeat
+        nsecs_t nextRepeatTime;
+    } mKeyRepeatState;
+
+    void resetKeyRepeatLocked();
+    KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime, nsecs_t keyRepeatTimeout);
+
+    // Deferred command processing.
+    bool runCommandsLockedInterruptible();
+    CommandEntry* postCommandLocked(Command command);
+
+    // Inbound event processing.
+    void drainInboundQueueLocked();
+    void releasePendingEventLocked();
+    void releaseInboundEventLocked(EventEntry* entry);
+
+    // Dispatch state.
+    bool mDispatchEnabled;
+    bool mDispatchFrozen;
+
+    Vector<InputWindow> mWindows;
+
+    const InputWindow* getWindowLocked(const sp<InputChannel>& inputChannel);
+
+    // Focus tracking for keys, trackball, etc.
+    const InputWindow* mFocusedWindow;
+
+    // Focus tracking for touch.
+    struct TouchedWindow {
+        const InputWindow* window;
+        int32_t targetFlags;
+        BitSet32 pointerIds;
+        sp<InputChannel> channel;
+    };
+    struct TouchState {
+        bool down;
+        bool split;
+        Vector<TouchedWindow> windows;
+
+        TouchState();
+        ~TouchState();
+        void reset();
+        void copyFrom(const TouchState& other);
+        void addOrUpdateWindow(const InputWindow* window, int32_t targetFlags, BitSet32 pointerIds);
+        void removeOutsideTouchWindows();
+        const InputWindow* getFirstForegroundWindow();
+    };
+
+    TouchState mTouchState;
+    TouchState mTempTouchState;
+
+    // Focused application.
+    InputApplication* mFocusedApplication;
+    InputApplication mFocusedApplicationStorage; // preallocated storage for mFocusedApplication
+    void releaseFocusedApplicationLocked();
+
+    // Dispatch inbound events.
+    bool dispatchConfigurationChangedLocked(
+            nsecs_t currentTime, ConfigurationChangedEntry* entry);
+    bool dispatchKeyLocked(
+            nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
+            DropReason* dropReason, nsecs_t* nextWakeupTime);
+    bool dispatchMotionLocked(
+            nsecs_t currentTime, MotionEntry* entry,
+            DropReason* dropReason, nsecs_t* nextWakeupTime);
+    void dispatchEventToCurrentInputTargetsLocked(
+            nsecs_t currentTime, EventEntry* entry, bool resumeWithAppendedMotionSample);
+
+    void logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry);
+    void logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry);
+
+    // The input targets that were most recently identified for dispatch.
+    bool mCurrentInputTargetsValid; // false while targets are being recomputed
+    Vector<InputTarget> mCurrentInputTargets;
+
+    enum InputTargetWaitCause {
+        INPUT_TARGET_WAIT_CAUSE_NONE,
+        INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY,
+        INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY,
+    };
+
+    InputTargetWaitCause mInputTargetWaitCause;
+    nsecs_t mInputTargetWaitStartTime;
+    nsecs_t mInputTargetWaitTimeoutTime;
+    bool mInputTargetWaitTimeoutExpired;
+
+    // Finding targets for input events.
+    void resetTargetsLocked();
+    void commitTargetsLocked();
+    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
+            const InputApplication* application, const InputWindow* window,
+            nsecs_t* nextWakeupTime);
+    void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
+            const sp<InputChannel>& inputChannel);
+    nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
+    void resetANRTimeoutsLocked();
+
+    int32_t findFocusedWindowTargetsLocked(nsecs_t currentTime, const EventEntry* entry,
+            nsecs_t* nextWakeupTime);
+    int32_t findTouchedWindowTargetsLocked(nsecs_t currentTime, const MotionEntry* entry,
+            nsecs_t* nextWakeupTime);
+
+    void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
+            BitSet32 pointerIds);
+    void addMonitoringTargetsLocked();
+    void pokeUserActivityLocked(const EventEntry* eventEntry);
+    bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
+    bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const;
+    bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
+    String8 getApplicationWindowLabelLocked(const InputApplication* application,
+            const InputWindow* window);
+
+    // 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 startNextDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+    void abortBrokenDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection);
+    void drainOutboundQueueLocked(Connection* connection);
+    static int handleReceiveCallback(int receiveFd, int events, void* data);
+
+    void synthesizeCancelationEventsForAllConnectionsLocked(
+            InputState::CancelationOptions options, const char* reason);
+    void synthesizeCancelationEventsForInputChannelLocked(const sp<InputChannel>& channel,
+            InputState::CancelationOptions options, const char* reason);
+    void synthesizeCancelationEventsForConnectionLocked(const sp<Connection>& connection,
+            InputState::CancelationOptions options, const char* reason);
+
+    // Splitting motion events across windows.
+    MotionEntry* splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds);
+
+    // Reset and drop everything the dispatcher is doing.
+    void resetAndDropEverythingLocked(const char* reason);
+
+    // Dump state.
+    void dumpDispatchStateLocked(String8& dump);
+    void logDispatchStateLocked();
+
+    // 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);
+    void onDispatchCycleBrokenLocked(
+            nsecs_t currentTime, const sp<Connection>& connection);
+    void onANRLocked(
+            nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
+            nsecs_t eventTime, nsecs_t waitStartTime);
+
+    // Outbound policy interactions.
+    void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
+    void doNotifyInputChannelBrokenLockedInterruptible(CommandEntry* commandEntry);
+    void doNotifyANRLockedInterruptible(CommandEntry* commandEntry);
+    void doInterceptKeyBeforeDispatchingLockedInterruptible(CommandEntry* commandEntry);
+    void doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry);
+
+    // Statistics gathering.
+    void updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
+            int32_t injectionResult, nsecs_t timeSpentWaitingForApplication);
+};
+
+/* 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_H
diff --git a/include/ui/InputManager.h b/include/ui/InputManager.h
new file mode 100644
index 0000000..568568b
--- /dev/null
+++ b/include/ui/InputManager.h
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+    /* Gets the input reader. */
+    virtual sp<InputReaderInterface> getReader() = 0;
+
+    /* Gets the input dispatcher. */
+    virtual sp<InputDispatcherInterface> getDispatcher() = 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 sp<InputReaderInterface> getReader();
+    virtual sp<InputDispatcherInterface> getDispatcher();
+
+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..49351b0
--- /dev/null
+++ b/include/ui/InputReader.h
@@ -0,0 +1,927 @@
+/*
+ * 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
+    };
+
+    /* 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;
+
+    /* 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:
+    /* Dumps the state of the input reader.
+     *
+     * This method may be called on any thread (usually by the input manager). */
+    virtual void dump(String8& dump) = 0;
+
+    /* 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 {
+public:
+    InputReaderContext() { }
+    virtual ~InputReaderContext() { }
+
+    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, protected InputReaderContext {
+public:
+    InputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputDispatcherInterface>& dispatcher);
+    virtual ~InputReader();
+
+    virtual void dump(String8& dump);
+
+    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);
+
+protected:
+    // These methods are protected virtual so they can be overridden and instrumented
+    // by test cases.
+    virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
+
+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(int32_t deviceId);
+    void removeDevice(int32_t deviceId);
+    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 dump(String8& dump);
+    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 dump(String8& dump);
+    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;
+};
+
+
+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 dump(String8& dump);
+    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);
+
+    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 dump(String8& dump);
+    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);
+};
+
+
+class TouchInputMapper : public InputMapper {
+public:
+    TouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~TouchInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void dump(String8& dump);
+    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:
+    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;
+
+        inline bool operator== (const PointerData& other) const {
+            return id == other.id
+                    && x == other.x
+                    && y == other.y
+                    && pressure == other.pressure
+                    && touchMajor == other.touchMajor
+                    && touchMinor == other.touchMinor
+                    && toolMajor == other.toolMajor
+                    && toolMinor == other.toolMinor
+                    && orientation == other.orientation;
+        }
+        inline bool operator!= (const PointerData& other) const {
+            return !(*this == other);
+        }
+    };
+
+    // 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 Size
+        enum TouchSizeCalibration {
+            TOUCH_SIZE_CALIBRATION_DEFAULT,
+            TOUCH_SIZE_CALIBRATION_NONE,
+            TOUCH_SIZE_CALIBRATION_GEOMETRIC,
+            TOUCH_SIZE_CALIBRATION_PRESSURE,
+        };
+
+        TouchSizeCalibration touchSizeCalibration;
+
+        // Tool Size
+        enum ToolSizeCalibration {
+            TOOL_SIZE_CALIBRATION_DEFAULT,
+            TOOL_SIZE_CALIBRATION_NONE,
+            TOOL_SIZE_CALIBRATION_GEOMETRIC,
+            TOOL_SIZE_CALIBRATION_LINEAR,
+            TOOL_SIZE_CALIBRATION_AREA,
+        };
+
+        ToolSizeCalibration toolSizeCalibration;
+        bool haveToolSizeLinearScale;
+        float toolSizeLinearScale;
+        bool haveToolSizeLinearBias;
+        float toolSizeLinearBias;
+        bool haveToolSizeAreaScale;
+        float toolSizeAreaScale;
+        bool haveToolSizeAreaBias;
+        float toolSizeAreaBias;
+        bool haveToolSizeIsSummed;
+        int32_t toolSizeIsSummed;
+
+        // 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 toolSizeLinearScale;
+        float toolSizeLinearBias;
+        float toolSizeAreaScale;
+        float toolSizeAreaBias;
+
+        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 haveTouchSize;
+            InputDeviceInfo::MotionRange touchMajor;
+            InputDeviceInfo::MotionRange touchMinor;
+
+            bool haveToolSize;
+            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 dumpParameters(String8& dump);
+    virtual void configureRawAxes();
+    virtual void dumpRawAxes(String8& dump);
+    virtual bool configureSurfaceLocked();
+    virtual void dumpSurfaceLocked(String8& dump);
+    virtual void configureVirtualKeysLocked();
+    virtual void dumpVirtualKeysLocked(String8& dump);
+    virtual void parseCalibration();
+    virtual void resolveCalibration();
+    virtual void dumpCalibration(String8& dump);
+
+    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);
+
+    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..dc9e27a
--- /dev/null
+++ b/include/ui/InputTransport.h
@@ -0,0 +1,335 @@
+/*
+ * 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/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
old mode 100644
new mode 100755
index 571e47b..f71d9cd
--- 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;
@@ -114,113 +116,33 @@
     { "MEDIA_REWIND", 89 },
     { "MEDIA_FAST_FORWARD", 90 },
     { "MUTE", 91 },
+    { "PAGE_UP", 92 },
+    { "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
-} KeyCode;
-
+// See also policy flags in Input.h.
 static const KeycodeLabel FLAGS[] = {
     { "WAKE", 0x00000001 },
     { "WAKE_DROPPED", 0x00000002 },
@@ -230,6 +152,7 @@
     { "ALT_GR", 0x00000020 },
     { "MENU", 0x00000040 },
     { "LAUNCHER", 0x00000080 },
+    { "VIRTUAL", 0x00000100 },
     { NULL, 0 }
 };
 
diff --git a/include/ui/PowerManager.h b/include/ui/PowerManager.h
new file mode 100644
index 0000000..5434b4f
--- /dev/null
+++ b/include/ui/PowerManager.h
@@ -0,0 +1,37 @@
+/*
+ * 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_POWER_MANAGER_H
+#define _UI_POWER_MANAGER_H
+
+
+namespace android {
+
+enum {
+    POWER_MANAGER_OTHER_EVENT = 0,
+    POWER_MANAGER_CHEEK_EVENT = 1,
+    POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either
+                                   // up events or LONG_TOUCH events.
+    POWER_MANAGER_LONG_TOUCH_EVENT = 3,
+    POWER_MANAGER_TOUCH_UP_EVENT = 4,
+    POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events.
+
+    POWER_MANAGER_LAST_EVENT = POWER_MANAGER_BUTTON_EVENT, // Last valid event code.
+};
+
+} // namespace android
+
+#endif // _UI_POWER_MANAGER_H
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..654d0f3 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,36 @@
      *     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;
+    /*
+     * hook used to cancel a buffer that has been dequeued.
+     * No synchronization is performed between dequeue() and cancel(), so
+     * either external synchronization is needed, or these functions must be
+     * called from the same thread.
+     */
+    int     (*cancelBuffer)(struct ANativeWindow* window,
+                struct android_native_buffer_t* buffer);
 
 
+    void* reserved_proc[2];
+};
+
+// 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 +246,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 +378,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..f5dbcd9
--- /dev/null
+++ b/include/utils/BitSet.h
@@ -0,0 +1,70 @@
+/*
+ * 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 the number of marked bits in the set.
+    inline uint32_t count() const { return __builtin_popcount(value); }
+
+    // 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/Looper.h b/include/utils/Looper.h
new file mode 100644
index 0000000..eefff31
--- /dev/null
+++ b/include/utils/Looper.h
@@ -0,0 +1,270 @@
+/*
+ * 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_LOOPER_H
+#define UTILS_LOOPER_H
+
+#include <utils/threads.h>
+#include <utils/RefBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/Timers.h>
+
+#include <android/looper.h>
+
+// When defined, uses epoll_wait() for polling, otherwise uses poll().
+#define LOOPER_USES_EPOLL
+
+// When defined, logs performance statistics for tuning and debugging purposes.
+//#define LOOPER_STATISTICS
+
+#ifdef LOOPER_USES_EPOLL
+#include <sys/epoll.h>
+#else
+#include <sys/poll.h>
+#endif
+
+/*
+ * Declare a concrete type for the NDK's looper forward declaration.
+ */
+struct ALooper {
+};
+
+namespace android {
+
+/**
+ * A polling loop that supports monitoring file descriptor events, optionally
+ * using callbacks.  The implementation uses epoll() internally.
+ *
+ * A looper can be associated with a thread although there is no requirement that it must be.
+ */
+class Looper : public ALooper, public RefBase {
+protected:
+    virtual ~Looper();
+
+public:
+    /**
+     * Creates a looper.
+     *
+     * If allowNonCallbaks is true, the looper will allow file descriptors to be
+     * registered without associated callbacks.  This assumes that the caller of
+     * pollOnce() is prepared to handle callback-less events itself.
+     */
+    Looper(bool allowNonCallbacks);
+
+    /**
+     * Returns whether this looper instance allows the registration of file descriptors
+     * using identifiers instead of callbacks.
+     */
+    bool getAllowNonCallbacks() const;
+
+    /**
+     * Waits for events to be available, 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 an event appears.
+     *
+     * Returns ALOOPER_POLL_WAKE if the poll was awoken using wake() before
+     * the timeout expired and no callbacks were invoked and no other file
+     * descriptors were ready.
+     *
+     * Returns ALOOPER_POLL_CALLBACK if one or more callbacks were invoked.
+     *
+     * Returns ALOOPER_POLL_TIMEOUT if there was no data before the given
+     * timeout expired.
+     *
+     * Returns ALOOPER_POLL_ERROR if an error occurred.
+     *
+     * Returns a value >= 0 containing an identifier if its file descriptor has data
+     * and it has no callback function (requiring the caller here to handle it).
+     * In this (and only this) case outFd, outEvents and outData will contain the poll
+     * events and data associated with the fd, otherwise they will be set to NULL.
+     *
+     * This method does not return until it has finished invoking the appropriate callbacks
+     * for all file descriptors that were signalled.
+     */
+    int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
+    inline int pollOnce(int timeoutMillis) {
+        return pollOnce(timeoutMillis, NULL, NULL, NULL);
+    }
+
+    /**
+     * Like pollOnce(), but performs all pending callbacks until all
+     * data has been consumed or a file descriptor is available with no callback.
+     * This function will never return ALOOPER_POLL_CALLBACK.
+     */
+    int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
+    inline int pollAll(int timeoutMillis) {
+        return pollAll(timeoutMillis, NULL, NULL, NULL);
+    }
+
+    /**
+     * Wakes the poll asynchronously.
+     *
+     * This method can be called on any thread.
+     * This method returns immediately.
+     */
+    void wake();
+
+    /**
+     * Adds a new file descriptor to be polled by the looper.
+     * If the same file descriptor was previously added, it is replaced.
+     *
+     * "fd" is the file descriptor to be added.
+     * "ident" is an identifier for this event, which is returned from ALooper_pollOnce().
+     * The identifier must be >= 0, or ALOOPER_POLL_CALLBACK if providing a non-NULL callback.
+     * "events" are the poll events to wake up on.  Typically this is ALOOPER_EVENT_INPUT.
+     * "callback" is the function to call when there is an event on the file descriptor.
+     * "data" is a private data pointer to supply to the callback.
+     *
+     * There are two main uses of this function:
+     *
+     * (1) If "callback" is non-NULL, then this function will be called when there is
+     * data on the file descriptor.  It should execute any events it has pending,
+     * appropriately reading from the file descriptor.  The 'ident' is ignored in this case.
+     *
+     * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
+     * when its file descriptor has data available, requiring the caller to take
+     * care of processing it.
+     *
+     * Returns 1 if the file descriptor was added, 0 if the arguments were invalid.
+     *
+     * This method can be called on any thread.
+     * This method may block briefly if it needs to wake the poll.
+     */
+    int addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data);
+
+    /**
+     * Removes a previously added file descriptor from the looper.
+     *
+     * When this method returns, it is safe to close the file descriptor since the looper
+     * 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 0 or by calling this method, then it can be guaranteed to not be invoked
+     * again at any later time unless registered anew.
+     *
+     * Returns 1 if the file descriptor was removed, 0 if none was previously registered.
+     *
+     * This method can be called on any thread.
+     * This method may block briefly if it needs to wake the poll.
+     */
+    int removeFd(int fd);
+
+    /**
+     * Prepares a looper associated with the calling thread, and returns it.
+     * If the thread already has a looper, it is returned.  Otherwise, a new
+     * one is created, associated with the thread, and returned.
+     *
+     * The opts may be ALOOPER_PREPARE_ALLOW_NON_CALLBACKS or 0.
+     */
+    static sp<Looper> prepare(int opts);
+
+    /**
+     * Sets the given looper to be associated with the calling thread.
+     * If another looper is already associated with the thread, it is replaced.
+     *
+     * If "looper" is NULL, removes the currently associated looper.
+     */
+    static void setForThread(const sp<Looper>& looper);
+
+    /**
+     * Returns the looper associated with the calling thread, or NULL if
+     * there is not one.
+     */
+    static sp<Looper> getForThread();
+
+private:
+    struct Request {
+        int fd;
+        int ident;
+        ALooper_callbackFunc callback;
+        void* data;
+    };
+
+    struct Response {
+        int events;
+        Request request;
+    };
+
+    const bool mAllowNonCallbacks; // immutable
+
+    int mWakeReadPipeFd;  // immutable
+    int mWakeWritePipeFd; // immutable
+    Mutex mLock;
+
+#ifdef LOOPER_USES_EPOLL
+    int mEpollFd; // immutable
+
+    // Locked list of file descriptor monitoring requests.
+    KeyedVector<int, Request> mRequests;  // guarded by mLock
+#else
+    // The lock guards state used to track whether there is a poll() in progress and whether
+    // there are any other threads waiting in wakeAndLock().  The condition variables
+    // are used to transfer control among these threads such that all waiters are
+    // serviced before a new poll can begin.
+    // The wakeAndLock() method increments mWaiters, wakes the poll, blocks on mAwake
+    // until mPolling becomes false, then decrements mWaiters again.
+    // The poll() method blocks on mResume until mWaiters becomes 0, then sets
+    // mPolling to true, blocks until the poll completes, then resets mPolling to false
+    // and signals mResume if there are waiters.
+    bool mPolling;      // guarded by mLock
+    uint32_t mWaiters;  // guarded by mLock
+    Condition mAwake;   // guarded by mLock
+    Condition mResume;  // guarded by mLock
+
+    Vector<struct pollfd> mRequestedFds;  // must hold mLock and mPolling must be false to modify
+    Vector<Request> mRequests;            // must hold mLock and mPolling must be false to modify
+
+    ssize_t getRequestIndexLocked(int fd);
+    void wakeAndLock();
+#endif
+
+#ifdef LOOPER_STATISTICS
+    static const int SAMPLED_WAKE_CYCLES_TO_AGGREGATE = 100;
+    static const int SAMPLED_POLLS_TO_AGGREGATE = 1000;
+
+    nsecs_t mPendingWakeTime;
+    int mPendingWakeCount;
+
+    int mSampledWakeCycles;
+    int mSampledWakeCountSum;
+    nsecs_t mSampledWakeLatencySum;
+
+    int mSampledPolls;
+    int mSampledZeroPollCount;
+    int mSampledZeroPollLatencySum;
+    int mSampledTimeoutPollCount;
+    int mSampledTimeoutPollLatencySum;
+#endif
+
+    // This state is only used privately by pollOnce and does not require a lock since
+    // it runs on a single thread.
+    Vector<Response> mResponses;
+    size_t mResponseIndex;
+
+    int pollInner(int timeoutMillis);
+    void awoken();
+    void pushResponse(int events, const Request& request);
+
+    static void initTLSKey();
+    static void threadDestructor(void *st);
+};
+
+} // namespace android
+
+#endif // UTILS_LOOPER_H
diff --git a/include/utils/ObbFile.h b/include/utils/ObbFile.h
new file mode 100644
index 0000000..47559cd
--- /dev/null
+++ b/include/utils/ObbFile.h
@@ -0,0 +1,145 @@
+/*
+ * 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)
+#define OBB_SALTED          (1 << 1)
+
+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;
+    }
+
+    const unsigned char* getSalt(size_t* length) const {
+        if ((mFlags & OBB_SALTED) == 0) {
+            *length = 0;
+            return NULL;
+        }
+
+        *length = sizeof(mSalt);
+        return mSalt;
+    }
+
+    bool setSalt(const unsigned char* salt, size_t length) {
+        if (length != sizeof(mSalt)) {
+            return false;
+        }
+
+        memcpy(mSalt, salt, sizeof(mSalt));
+        mFlags |= OBB_SALTED;
+        return true;
+    }
+
+    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;
+
+    /* Whether the file is salted. */
+    bool mSalted;
+
+    /* The encryption salt. */
+    unsigned char mSalt[8];
+
+    const char* mFileName;
+
+    size_t mFileSize;
+
+    size_t mFooterStart;
+
+    unsigned char* mReadBuf;
+
+    bool parseObbFile(int fd);
+};
+
+}
+#endif /* OBBFILE_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..3c1f3ca 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -14,18 +14,25 @@
  * limitations under the License.
  */
 
-//
-// Read-only access to Zip archives, with minimal heap allocation.
-//
-// This is similar to the more-complete ZipFile class, but no attempt
-// has been made to make them interchangeable.  This class operates under
-// a very different set of assumptions and constraints.
-//
+/*
+ * Read-only access to Zip archives, with minimal heap allocation.
+ *
+ * This is similar to the more-complete ZipFile class, but no attempt
+ * has been made to make them interchangeable.  This class operates under
+ * a very different set of assumptions and constraints.
+ *
+ * One such assumption is that if you're getting file descriptors for
+ * use with this class as a child of a fork() operation, you must be on
+ * a pread() to guarantee correct operation. This is because pread() can
+ * atomically read at a file offset without worrying about a lock around an
+ * lseek() + read() pair.
+ */
 #ifndef __LIBS_ZIPFILERO_H
 #define __LIBS_ZIPFILERO_H
 
-#include "Errors.h"
-#include "FileMap.h"
+#include <utils/Errors.h>
+#include <utils/FileMap.h>
+#include <utils/threads.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -54,19 +61,21 @@
  * the record structure.  However, this requires a private mapping of
  * every page that the Central Directory touches.  Easier to tuck a copy
  * of the string length into the hash table entry.
+ *
+ * NOTE: If this is used on file descriptors inherited from a fork() operation,
+ * you must be on a platform that implements pread() to guarantee correctness
+ * on the shared file descriptors.
  */
 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 (mFd >= 0)
-            close(mFd);
-    }
+
+    ~ZipFileRO();
 
     /*
      * Open an archive.
@@ -118,8 +127,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 +164,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 +188,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 +215,24 @@
     /* open Zip archive */
     int         mFd;
 
+    /* Lock for handling the file descriptor (seeks, etc) */
+    mutable Mutex mFdLock;
+
+    /* 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/audioflinger/A2dpAudioInterface.cpp b/libs/audioflinger/A2dpAudioInterface.cpp
deleted file mode 100644
index 995e31c..0000000
--- a/libs/audioflinger/A2dpAudioInterface.cpp
+++ /dev/null
@@ -1,466 +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.
- */
-
-#include <math.h>
-
-//#define LOG_NDEBUG 0
-#define LOG_TAG "A2dpAudioInterface"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "A2dpAudioInterface.h"
-#include "audio/liba2dp.h"
-
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-//AudioHardwareInterface* A2dpAudioInterface::createA2dpInterface()
-//{
-//    AudioHardwareInterface* hw = 0;
-//
-//    hw = AudioHardwareInterface::create();
-//    LOGD("new A2dpAudioInterface(hw: %p)", hw);
-//    hw = new A2dpAudioInterface(hw);
-//    return hw;
-//}
-
-A2dpAudioInterface::A2dpAudioInterface(AudioHardwareInterface* hw) :
-    mOutput(0), mHardwareInterface(hw), mBluetoothEnabled(true), mSuspended(false)
-{
-}
-
-A2dpAudioInterface::~A2dpAudioInterface()
-{
-    closeOutputStream((AudioStreamOut *)mOutput);
-    delete mHardwareInterface;
-}
-
-status_t A2dpAudioInterface::initCheck()
-{
-    if (mHardwareInterface == 0) return NO_INIT;
-    return mHardwareInterface->initCheck();
-}
-
-AudioStreamOut* A2dpAudioInterface::openOutputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
-    if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) {
-        LOGV("A2dpAudioInterface::openOutputStream() open HW device: %x", devices);
-        return mHardwareInterface->openOutputStream(devices, format, channels, sampleRate, status);
-    }
-
-    status_t err = 0;
-
-    // only one output stream allowed
-    if (mOutput) {
-        if (status)
-            *status = -1;
-        return NULL;
-    }
-
-    // create new output stream
-    A2dpAudioStreamOut* out = new A2dpAudioStreamOut();
-    if ((err = out->set(devices, format, channels, sampleRate)) == NO_ERROR) {
-        mOutput = out;
-        mOutput->setBluetoothEnabled(mBluetoothEnabled);
-        mOutput->setSuspended(mSuspended);
-    } else {
-        delete out;
-    }
-
-    if (status)
-        *status = err;
-    return mOutput;
-}
-
-void A2dpAudioInterface::closeOutputStream(AudioStreamOut* out) {
-    if (mOutput == 0 || mOutput != out) {
-        mHardwareInterface->closeOutputStream(out);
-    }
-    else {
-        delete mOutput;
-        mOutput = 0;
-    }
-}
-
-
-AudioStreamIn* A2dpAudioInterface::openInputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status,
-        AudioSystem::audio_in_acoustics acoustics)
-{
-    return mHardwareInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
-}
-
-void A2dpAudioInterface::closeInputStream(AudioStreamIn* in)
-{
-    return mHardwareInterface->closeInputStream(in);
-}
-
-status_t A2dpAudioInterface::setMode(int mode)
-{
-    return mHardwareInterface->setMode(mode);
-}
-
-status_t A2dpAudioInterface::setMicMute(bool state)
-{
-    return mHardwareInterface->setMicMute(state);
-}
-
-status_t A2dpAudioInterface::getMicMute(bool* state)
-{
-    return mHardwareInterface->getMicMute(state);
-}
-
-status_t A2dpAudioInterface::setParameters(const String8& keyValuePairs)
-{
-    AudioParameter param = AudioParameter(keyValuePairs);
-    String8 value;
-    String8 key;
-    status_t status = NO_ERROR;
-
-    LOGV("setParameters() %s", keyValuePairs.string());
-
-    key = "bluetooth_enabled";
-    if (param.get(key, value) == NO_ERROR) {
-        mBluetoothEnabled = (value == "true");
-        if (mOutput) {
-            mOutput->setBluetoothEnabled(mBluetoothEnabled);
-        }
-        param.remove(key);
-    }
-    key = String8("A2dpSuspended");
-    if (param.get(key, value) == NO_ERROR) {
-        mSuspended = (value == "true");
-        if (mOutput) {
-            mOutput->setSuspended(mSuspended);
-        }
-        param.remove(key);
-    }
-
-    if (param.size()) {
-        status_t hwStatus = mHardwareInterface->setParameters(param.toString());
-        if (status == NO_ERROR) {
-            status = hwStatus;
-        }
-    }
-
-    return status;
-}
-
-String8 A2dpAudioInterface::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    AudioParameter a2dpParam = AudioParameter();
-    String8 value;
-    String8 key;
-
-    key = "bluetooth_enabled";
-    if (param.get(key, value) == NO_ERROR) {
-        value = mBluetoothEnabled ? "true" : "false";
-        a2dpParam.add(key, value);
-        param.remove(key);
-    }
-    key = "A2dpSuspended";
-    if (param.get(key, value) == NO_ERROR) {
-        value = mSuspended ? "true" : "false";
-        a2dpParam.add(key, value);
-        param.remove(key);
-    }
-
-    String8 keyValuePairs  = a2dpParam.toString();
-
-    if (param.size()) {
-        if (keyValuePairs != "") {
-            keyValuePairs += ";";
-        }
-        keyValuePairs += mHardwareInterface->getParameters(param.toString());
-    }
-
-    LOGV("getParameters() %s", keyValuePairs.string());
-    return keyValuePairs;
-}
-
-size_t A2dpAudioInterface::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
-    return mHardwareInterface->getInputBufferSize(sampleRate, format, channelCount);
-}
-
-status_t A2dpAudioInterface::setVoiceVolume(float v)
-{
-    return mHardwareInterface->setVoiceVolume(v);
-}
-
-status_t A2dpAudioInterface::setMasterVolume(float v)
-{
-    return mHardwareInterface->setMasterVolume(v);
-}
-
-status_t A2dpAudioInterface::dump(int fd, const Vector<String16>& args)
-{
-    return mHardwareInterface->dumpState(fd, args);
-}
-
-// ----------------------------------------------------------------------------
-
-A2dpAudioInterface::A2dpAudioStreamOut::A2dpAudioStreamOut() :
-    mFd(-1), mStandby(true), mStartCount(0), mRetryCount(0), mData(NULL),
-    // assume BT enabled to start, this is safe because its only the
-    // enabled->disabled transition we are worried about
-    mBluetoothEnabled(true), mDevice(0), mClosing(false), mSuspended(false)
-{
-    // use any address by default
-    strcpy(mA2dpAddress, "00:00:00:00:00:00");
-    init();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::set(
-        uint32_t device, int *pFormat, uint32_t *pChannels, uint32_t *pRate)
-{
-    int lFormat = pFormat ? *pFormat : 0;
-    uint32_t lChannels = pChannels ? *pChannels : 0;
-    uint32_t lRate = pRate ? *pRate : 0;
-
-    LOGD("A2dpAudioStreamOut::set %x, %d, %d, %d\n", device, lFormat, lChannels, lRate);
-
-    // fix up defaults
-    if (lFormat == 0) lFormat = format();
-    if (lChannels == 0) lChannels = channels();
-    if (lRate == 0) lRate = sampleRate();
-
-    // check values
-    if ((lFormat != format()) ||
-            (lChannels != channels()) ||
-            (lRate != sampleRate())){
-        if (pFormat) *pFormat = format();
-        if (pChannels) *pChannels = channels();
-        if (pRate) *pRate = sampleRate();
-        return BAD_VALUE;
-    }
-
-    if (pFormat) *pFormat = lFormat;
-    if (pChannels) *pChannels = lChannels;
-    if (pRate) *pRate = lRate;
-
-    mDevice = device;
-    return NO_ERROR;
-}
-
-A2dpAudioInterface::A2dpAudioStreamOut::~A2dpAudioStreamOut()
-{
-    LOGV("A2dpAudioStreamOut destructor");
-    standby();
-    close();
-    LOGV("A2dpAudioStreamOut destructor returning from close()");
-}
-
-ssize_t A2dpAudioInterface::A2dpAudioStreamOut::write(const void* buffer, size_t bytes)
-{
-    Mutex::Autolock lock(mLock);
-
-    size_t remaining = bytes;
-    status_t status = -1;
-
-    if (!mBluetoothEnabled || mClosing || mSuspended) {
-        LOGV("A2dpAudioStreamOut::write(), but bluetooth disabled \
-               mBluetoothEnabled %d, mClosing %d, mSuspended %d",
-                mBluetoothEnabled, mClosing, mSuspended);
-        goto Error;
-    }
-
-    status = init();
-    if (status < 0)
-        goto Error;
-
-    while (remaining > 0) {
-        status = a2dp_write(mData, buffer, remaining);
-        if (status <= 0) {
-            LOGE("a2dp_write failed err: %d\n", status);
-            goto Error;
-        }
-        remaining -= status;
-        buffer = ((char *)buffer) + status;
-    }
-
-    mStandby = false;
-
-    return bytes;
-
-Error:
-    // Simulate audio output timing in case of error
-    usleep(((bytes * 1000 )/ frameSize() / sampleRate()) * 1000);
-
-    return status;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::init()
-{
-    if (!mData) {
-        status_t status = a2dp_init(44100, 2, &mData);
-        if (status < 0) {
-            LOGE("a2dp_init failed err: %d\n", status);
-            mData = NULL;
-            return status;
-        }
-        a2dp_set_sink(mData, mA2dpAddress);
-    }
-
-    return 0;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::standby()
-{
-    int result = 0;
-
-    if (mClosing) {
-        LOGV("Ignore standby, closing");
-        return result;
-    }
-
-    Mutex::Autolock lock(mLock);
-
-    if (!mStandby) {
-        result = a2dp_stop(mData);
-        if (result == 0)
-            mStandby = true;
-    }
-
-    return result;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setParameters(const String8& keyValuePairs)
-{
-    AudioParameter param = AudioParameter(keyValuePairs);
-    String8 value;
-    String8 key = String8("a2dp_sink_address");
-    status_t status = NO_ERROR;
-    int device;
-    LOGV("A2dpAudioStreamOut::setParameters() %s", keyValuePairs.string());
-
-    if (param.get(key, value) == NO_ERROR) {
-        if (value.length() != strlen("00:00:00:00:00:00")) {
-            status = BAD_VALUE;
-        } else {
-            setAddress(value.string());
-        }
-        param.remove(key);
-    }
-    key = String8("closing");
-    if (param.get(key, value) == NO_ERROR) {
-        mClosing = (value == "true");
-        param.remove(key);
-    }
-    key = AudioParameter::keyRouting;
-    if (param.getInt(key, device) == NO_ERROR) {
-        if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)device)) {
-            mDevice = device;
-            status = NO_ERROR;
-        } else {
-            status = BAD_VALUE;
-        }
-        param.remove(key);
-    }
-
-    if (param.size()) {
-        status = BAD_VALUE;
-    }
-    return status;
-}
-
-String8 A2dpAudioInterface::A2dpAudioStreamOut::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    String8 value;
-    String8 key = String8("a2dp_sink_address");
-
-    if (param.get(key, value) == NO_ERROR) {
-        value = mA2dpAddress;
-        param.add(key, value);
-    }
-    key = AudioParameter::keyRouting;
-    if (param.get(key, value) == NO_ERROR) {
-        param.addInt(key, (int)mDevice);
-    }
-
-    LOGV("A2dpAudioStreamOut::getParameters() %s", param.toString().string());
-    return param.toString();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setAddress(const char* address)
-{
-    Mutex::Autolock lock(mLock);
-
-    if (strlen(address) != strlen("00:00:00:00:00:00"))
-        return -EINVAL;
-
-    strcpy(mA2dpAddress, address);
-    if (mData)
-        a2dp_set_sink(mData, mA2dpAddress);
-
-    return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setBluetoothEnabled(bool enabled)
-{
-    LOGD("setBluetoothEnabled %d", enabled);
-
-    Mutex::Autolock lock(mLock);
-
-    mBluetoothEnabled = enabled;
-    if (!enabled) {
-        return close_l();
-    }
-    return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::setSuspended(bool onOff)
-{
-    LOGV("setSuspended %d", onOff);
-    mSuspended = onOff;
-    standby();
-    return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::close()
-{
-    Mutex::Autolock lock(mLock);
-    LOGV("A2dpAudioStreamOut::close() calling close_l()");
-    return close_l();
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::close_l()
-{
-    if (mData) {
-        LOGV("A2dpAudioStreamOut::close_l() calling a2dp_cleanup(mData)");
-        a2dp_cleanup(mData);
-        mData = NULL;
-    }
-    return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::dump(int fd, const Vector<String16>& args)
-{
-    return NO_ERROR;
-}
-
-status_t A2dpAudioInterface::A2dpAudioStreamOut::getRenderPosition(uint32_t *driverFrames)
-{
-    //TODO: enable when supported by driver
-    return INVALID_OPERATION;
-}
-
-}; // namespace android
diff --git a/libs/audioflinger/A2dpAudioInterface.h b/libs/audioflinger/A2dpAudioInterface.h
deleted file mode 100644
index 48154f9..0000000
--- a/libs/audioflinger/A2dpAudioInterface.h
+++ /dev/null
@@ -1,135 +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 A2DP_AUDIO_HARDWARE_H
-#define A2DP_AUDIO_HARDWARE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-
-namespace android {
-
-class A2dpAudioInterface : public AudioHardwareBase
-{
-    class A2dpAudioStreamOut;
-
-public:
-                        A2dpAudioInterface(AudioHardwareInterface* hw);
-    virtual             ~A2dpAudioInterface();
-    virtual status_t    initCheck();
-
-    virtual status_t    setVoiceVolume(float volume);
-    virtual status_t    setMasterVolume(float volume);
-
-    virtual status_t    setMode(int mode);
-
-    // mic mute
-    virtual status_t    setMicMute(bool state);
-    virtual status_t    getMicMute(bool* state);
-
-    virtual status_t    setParameters(const String8& keyValuePairs);
-    virtual String8     getParameters(const String8& keys);
-
-    virtual size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
-
-    // create I/O streams
-    virtual AudioStreamOut* openOutputStream(
-                                uint32_t devices,
-                                int *format=0,
-                                uint32_t *channels=0,
-                                uint32_t *sampleRate=0,
-                                status_t *status=0);
-    virtual    void        closeOutputStream(AudioStreamOut* out);
-
-    virtual AudioStreamIn* openInputStream(
-                                uint32_t devices,
-                                int *format,
-                                uint32_t *channels,
-                                uint32_t *sampleRate,
-                                status_t *status,
-                                AudioSystem::audio_in_acoustics acoustics);
-    virtual    void        closeInputStream(AudioStreamIn* in);
-//    static AudioHardwareInterface* createA2dpInterface();
-
-protected:
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-
-private:
-    class A2dpAudioStreamOut : public AudioStreamOut {
-    public:
-                            A2dpAudioStreamOut();
-        virtual             ~A2dpAudioStreamOut();
-                status_t    set(uint32_t device,
-                                int *pFormat,
-                                uint32_t *pChannels,
-                                uint32_t *pRate);
-        virtual uint32_t    sampleRate() const { return 44100; }
-        // SBC codec wants a multiple of 512
-        virtual size_t      bufferSize() const { return 512 * 20; }
-        virtual uint32_t    channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
-        virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-        virtual uint32_t    latency() const { return ((1000*bufferSize())/frameSize())/sampleRate() + 200; }
-        virtual status_t    setVolume(float left, float right) { return INVALID_OPERATION; }
-        virtual ssize_t     write(const void* buffer, size_t bytes);
-                status_t    standby();
-        virtual status_t    dump(int fd, const Vector<String16>& args);
-        virtual status_t    setParameters(const String8& keyValuePairs);
-        virtual String8     getParameters(const String8& keys);
-        virtual status_t    getRenderPosition(uint32_t *dspFrames);
-
-    private:
-        friend class A2dpAudioInterface;
-                status_t    init();
-                status_t    close();
-                status_t    close_l();
-                status_t    setAddress(const char* address);
-                status_t    setBluetoothEnabled(bool enabled);
-                status_t    setSuspended(bool onOff);
-
-    private:
-                int         mFd;
-                bool        mStandby;
-                int         mStartCount;
-                int         mRetryCount;
-                char        mA2dpAddress[20];
-                void*       mData;
-                Mutex       mLock;
-                bool        mBluetoothEnabled;
-                uint32_t    mDevice;
-                bool        mClosing;
-                bool        mSuspended;
-    };
-
-    friend class A2dpAudioStreamOut;
-
-    A2dpAudioStreamOut*     mOutput;
-    AudioHardwareInterface  *mHardwareInterface;
-    char        mA2dpAddress[20];
-    bool        mBluetoothEnabled;
-    bool        mSuspended;
-};
-
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // A2DP_AUDIO_HARDWARE_H
diff --git a/libs/audioflinger/Android.mk b/libs/audioflinger/Android.mk
deleted file mode 100644
index 870c0b8..0000000
--- a/libs/audioflinger/Android.mk
+++ /dev/null
@@ -1,130 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-
-#AUDIO_POLICY_TEST := true
-#ENABLE_AUDIO_DUMP := true
-
-include $(CLEAR_VARS)
-
-
-ifeq ($(AUDIO_POLICY_TEST),true)
-  ENABLE_AUDIO_DUMP := true
-endif
-
-
-LOCAL_SRC_FILES:= \
-    AudioHardwareGeneric.cpp \
-    AudioHardwareStub.cpp \
-    AudioHardwareInterface.cpp
-
-ifeq ($(ENABLE_AUDIO_DUMP),true)
-  LOCAL_SRC_FILES += AudioDumpInterface.cpp
-  LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
-endif
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    libbinder \
-    libmedia \
-    libhardware_legacy
-
-ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
-  LOCAL_CFLAGS += -DGENERIC_AUDIO
-endif
-
-LOCAL_MODULE:= libaudiointerface
-
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
-  LOCAL_SRC_FILES += A2dpAudioInterface.cpp
-  LOCAL_SHARED_LIBRARIES += liba2dp
-  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
-  LOCAL_C_INCLUDES += $(call include-path-for, bluez)
-endif
-
-include $(BUILD_STATIC_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=               \
-    AudioPolicyManagerBase.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    libmedia
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-LOCAL_MODULE:= libaudiopolicybase
-
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
-  LOCAL_CFLAGS += -DWITH_A2DP
-endif
-
-ifeq ($(AUDIO_POLICY_TEST),true)
-  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
-endif
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:=               \
-    AudioFlinger.cpp            \
-    AudioMixer.cpp.arm          \
-    AudioResampler.cpp.arm      \
-    AudioResamplerSinc.cpp.arm  \
-    AudioResamplerCubic.cpp.arm \
-    AudioPolicyService.cpp
-
-LOCAL_SHARED_LIBRARIES := \
-    libcutils \
-    libutils \
-    libbinder \
-    libmedia \
-    libhardware_legacy
-
-ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
-  LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
-  LOCAL_CFLAGS += -DGENERIC_AUDIO
-else
-  LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
-endif
-
-ifeq ($(TARGET_SIMULATOR),true)
- LOCAL_LDLIBS += -ldl
-else
- LOCAL_SHARED_LIBRARIES += libdl
-endif
-
-LOCAL_MODULE:= libaudioflinger
-
-ifeq ($(BOARD_HAVE_BLUETOOTH),true)
-  LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
-  LOCAL_SHARED_LIBRARIES += liba2dp
-endif
-
-ifeq ($(AUDIO_POLICY_TEST),true)
-  LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
-endif
-
-ifeq ($(TARGET_SIMULATOR),true)
-    ifeq ($(HOST_OS),linux)
-        LOCAL_LDLIBS += -lrt -lpthread
-    endif
-endif
-
-ifeq ($(BOARD_USE_LVMX),true)
-    LOCAL_CFLAGS += -DLVMX
-    LOCAL_C_INCLUDES += vendor/nxp
-    LOCAL_STATIC_LIBRARIES += liblifevibes
-    LOCAL_SHARED_LIBRARIES += liblvmxservice
-#    LOCAL_SHARED_LIBRARIES += liblvmxipc
-endif
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/audioflinger/AudioBufferProvider.h b/libs/audioflinger/AudioBufferProvider.h
deleted file mode 100644
index 81c5c39..0000000
--- a/libs/audioflinger/AudioBufferProvider.h
+++ /dev/null
@@ -1,49 +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_AUDIO_BUFFER_PROVIDER_H
-#define ANDROID_AUDIO_BUFFER_PROVIDER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Errors.h>
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-class AudioBufferProvider
-{
-public:
-
-    struct Buffer {
-        union {
-            void*       raw;
-            short*      i16;
-            int8_t*     i8;
-        };
-        size_t frameCount;
-    };
-
-    virtual ~AudioBufferProvider() {}
-    
-    virtual status_t getNextBuffer(Buffer* buffer) = 0;
-    virtual void releaseBuffer(Buffer* buffer) = 0;
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_AUDIO_BUFFER_PROVIDER_H
diff --git a/libs/audioflinger/AudioDumpInterface.cpp b/libs/audioflinger/AudioDumpInterface.cpp
deleted file mode 100644
index a018b4c..0000000
--- a/libs/audioflinger/AudioDumpInterface.cpp
+++ /dev/null
@@ -1,531 +0,0 @@
-/* //device/servers/AudioFlinger/AudioDumpInterface.cpp
-**
-** Copyright 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.
-*/
-
-#define LOG_TAG "AudioFlingerDump"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/Log.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "AudioDumpInterface.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-AudioDumpInterface::AudioDumpInterface(AudioHardwareInterface* hw)
-    : mFirstHwOutput(true), mPolicyCommands(String8("")), mFileName(String8(""))
-{
-    if(hw == 0) {
-        LOGE("Dump construct hw = 0");
-    }
-    mFinalInterface = hw;
-    LOGV("Constructor %p, mFinalInterface %p", this, mFinalInterface);
-}
-
-
-AudioDumpInterface::~AudioDumpInterface()
-{
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        closeOutputStream((AudioStreamOut *)mOutputs[i]);
-    }
-    if(mFinalInterface) delete mFinalInterface;
-}
-
-
-AudioStreamOut* AudioDumpInterface::openOutputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
-    AudioStreamOut* outFinal = NULL;
-    int lFormat = AudioSystem::PCM_16_BIT;
-    uint32_t lChannels = AudioSystem::CHANNEL_OUT_STEREO;
-    uint32_t lRate = 44100;
-
-
-    if (AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices) || mFirstHwOutput) {
-        outFinal = mFinalInterface->openOutputStream(devices, format, channels, sampleRate, status);
-        if (outFinal != 0) {
-            lFormat = outFinal->format();
-            lChannels = outFinal->channels();
-            lRate = outFinal->sampleRate();
-            if (!AudioSystem::isA2dpDevice((AudioSystem::audio_devices)devices)) {
-                mFirstHwOutput = false;
-            }
-        }
-    } else {
-        if (format != 0 && *format != 0) {
-            lFormat = *format;
-        } else {
-            lFormat = AudioSystem::PCM_16_BIT;
-        }
-        if (channels != 0 && *channels != 0) {
-            lChannels = *channels;
-        } else {
-            lChannels = AudioSystem::CHANNEL_OUT_STEREO;
-        }
-        if (sampleRate != 0 && *sampleRate != 0) {
-            lRate = *sampleRate;
-        } else {
-            lRate = 44100;
-        }
-        if (status) *status = NO_ERROR;
-    }
-    LOGV("openOutputStream(), outFinal %p", outFinal);
-
-    AudioStreamOutDump *dumOutput = new AudioStreamOutDump(this, mOutputs.size(), outFinal,
-            devices, lFormat, lChannels, lRate);
-    mOutputs.add(dumOutput);
-
-    return dumOutput;
-}
-
-void AudioDumpInterface::closeOutputStream(AudioStreamOut* out)
-{
-    AudioStreamOutDump *dumpOut = (AudioStreamOutDump *)out;
-
-    if (mOutputs.indexOf(dumpOut) < 0) {
-        LOGW("Attempt to close invalid output stream");
-        return;
-    }
-
-    LOGV("closeOutputStream() output %p", out);
-
-    dumpOut->standby();
-    if (dumpOut->finalStream() != NULL) {
-        mFinalInterface->closeOutputStream(dumpOut->finalStream());
-        mFirstHwOutput = true;
-    }
-
-    mOutputs.remove(dumpOut);
-    delete dumpOut;
-}
-
-AudioStreamIn* AudioDumpInterface::openInputStream(uint32_t devices, int *format, uint32_t *channels,
-        uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
-    AudioStreamIn* inFinal = NULL;
-    int lFormat = AudioSystem::PCM_16_BIT;
-    uint32_t lChannels = AudioSystem::CHANNEL_IN_MONO;
-    uint32_t lRate = 8000;
-
-
-    if (mInputs.size() == 0) {
-        inFinal = mFinalInterface->openInputStream(devices, format, channels, sampleRate, status, acoustics);
-        if (inFinal == 0) return 0;
-
-        lFormat = inFinal->format();
-        lChannels = inFinal->channels();
-        lRate = inFinal->sampleRate();
-    } else {
-        if (format != 0 && *format != 0) lFormat = *format;
-        if (channels != 0 && *channels != 0) lChannels = *channels;
-        if (sampleRate != 0 && *sampleRate != 0) lRate = *sampleRate;
-        if (status) *status = NO_ERROR;
-    }
-    LOGV("openInputStream(), inFinal %p", inFinal);
-
-    AudioStreamInDump *dumInput = new AudioStreamInDump(this, mInputs.size(), inFinal,
-            devices, lFormat, lChannels, lRate);
-    mInputs.add(dumInput);
-
-    return dumInput;
-}
-void AudioDumpInterface::closeInputStream(AudioStreamIn* in)
-{
-    AudioStreamInDump *dumpIn = (AudioStreamInDump *)in;
-
-    if (mInputs.indexOf(dumpIn) < 0) {
-        LOGW("Attempt to close invalid input stream");
-        return;
-    }
-    dumpIn->standby();
-    if (dumpIn->finalStream() != NULL) {
-        mFinalInterface->closeInputStream(dumpIn->finalStream());
-    }
-
-    mInputs.remove(dumpIn);
-    delete dumpIn;
-}
-
-
-status_t AudioDumpInterface::setParameters(const String8& keyValuePairs)
-{
-    AudioParameter param = AudioParameter(keyValuePairs);
-    String8 value;
-    int valueInt;
-    LOGV("setParameters %s", keyValuePairs.string());
-
-    if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
-        mFileName = value;
-        param.remove(String8("test_cmd_file_name"));
-    }
-    if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
-        Mutex::Autolock _l(mLock);
-        param.remove(String8("test_cmd_policy"));
-        mPolicyCommands = param.toString();
-        LOGV("test_cmd_policy command %s written", mPolicyCommands.string());
-        return NO_ERROR;
-    }
-
-    if (mFinalInterface != 0 ) return mFinalInterface->setParameters(keyValuePairs);
-    return NO_ERROR;
-}
-
-String8 AudioDumpInterface::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    AudioParameter response;
-    String8 value;
-
-//    LOGV("getParameters %s", keys.string());
-    if (param.get(String8("test_cmd_policy"), value) == NO_ERROR) {
-        Mutex::Autolock _l(mLock);
-        if (mPolicyCommands.length() != 0) {
-            response = AudioParameter(mPolicyCommands);
-            response.addInt(String8("test_cmd_policy"), 1);
-        } else {
-            response.addInt(String8("test_cmd_policy"), 0);
-        }
-        param.remove(String8("test_cmd_policy"));
-//        LOGV("test_cmd_policy command %s read", mPolicyCommands.string());
-    }
-
-    if (param.get(String8("test_cmd_file_name"), value) == NO_ERROR) {
-        response.add(String8("test_cmd_file_name"), mFileName);
-        param.remove(String8("test_cmd_file_name"));
-    }
-
-    String8 keyValuePairs = response.toString();
-
-    if (param.size() && mFinalInterface != 0 ) {
-        keyValuePairs += ";";
-        keyValuePairs += mFinalInterface->getParameters(param.toString());
-    }
-
-    return keyValuePairs;
-}
-
-
-// ----------------------------------------------------------------------------
-
-AudioStreamOutDump::AudioStreamOutDump(AudioDumpInterface *interface,
-                                        int id,
-                                        AudioStreamOut* finalStream,
-                                        uint32_t devices,
-                                        int format,
-                                        uint32_t channels,
-                                        uint32_t sampleRate)
-    : mInterface(interface), mId(id),
-      mSampleRate(sampleRate), mFormat(format), mChannels(channels), mLatency(0), mDevice(devices),
-      mBufferSize(1024), mFinalStream(finalStream), mOutFile(0), mFileCount(0)
-{
-    LOGV("AudioStreamOutDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
-}
-
-
-AudioStreamOutDump::~AudioStreamOutDump()
-{
-    LOGV("AudioStreamOutDump destructor");
-    Close();
-}
-
-ssize_t AudioStreamOutDump::write(const void* buffer, size_t bytes)
-{
-    ssize_t ret;
-
-    if (mFinalStream) {
-        ret = mFinalStream->write(buffer, bytes);
-    } else {
-        usleep((bytes * 1000000) / frameSize() / sampleRate());
-        ret = bytes;
-    }
-    if(!mOutFile) {
-        if (mInterface->fileName() != "") {
-            char name[255];
-            sprintf(name, "%s_%d_%d.pcm", mInterface->fileName().string(), mId, ++mFileCount);
-            mOutFile = fopen(name, "wb");
-            LOGV("Opening dump file %s, fh %p", name, mOutFile);
-        }
-    }
-    if (mOutFile) {
-        fwrite(buffer, bytes, 1, mOutFile);
-    }
-    return ret;
-}
-
-status_t AudioStreamOutDump::standby()
-{
-    LOGV("AudioStreamOutDump standby(), mOutFile %p, mFinalStream %p", mOutFile, mFinalStream);
-
-    Close();
-    if (mFinalStream != 0 ) return mFinalStream->standby();
-    return NO_ERROR;
-}
-
-uint32_t AudioStreamOutDump::sampleRate() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->sampleRate();
-    return mSampleRate;
-}
-
-size_t AudioStreamOutDump::bufferSize() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->bufferSize();
-    return mBufferSize;
-}
-
-uint32_t AudioStreamOutDump::channels() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->channels();
-    return mChannels;
-}
-int AudioStreamOutDump::format() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->format();
-    return mFormat;
-}
-uint32_t AudioStreamOutDump::latency() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->latency();
-    return 0;
-}
-status_t AudioStreamOutDump::setVolume(float left, float right)
-{
-    if (mFinalStream != 0 ) return mFinalStream->setVolume(left, right);
-    return NO_ERROR;
-}
-status_t AudioStreamOutDump::setParameters(const String8& keyValuePairs)
-{
-    LOGV("AudioStreamOutDump::setParameters %s", keyValuePairs.string());
-
-    if (mFinalStream != 0 ) {
-        return mFinalStream->setParameters(keyValuePairs);
-    }
-
-    AudioParameter param = AudioParameter(keyValuePairs);
-    String8 value;
-    int valueInt;
-    status_t status = NO_ERROR;
-
-    if (param.getInt(String8("set_id"), valueInt) == NO_ERROR) {
-        mId = valueInt;
-    }
-
-    if (param.getInt(String8("format"), valueInt) == NO_ERROR) {
-        if (mOutFile == 0) {
-            mFormat = valueInt;
-        } else {
-            status = INVALID_OPERATION;
-        }
-    }
-    if (param.getInt(String8("channels"), valueInt) == NO_ERROR) {
-        if (valueInt == AudioSystem::CHANNEL_OUT_STEREO || valueInt == AudioSystem::CHANNEL_OUT_MONO) {
-            mChannels = valueInt;
-        } else {
-            status = BAD_VALUE;
-        }
-    }
-    if (param.getInt(String8("sampling_rate"), valueInt) == NO_ERROR) {
-        if (valueInt > 0 && valueInt <= 48000) {
-            if (mOutFile == 0) {
-                mSampleRate = valueInt;
-            } else {
-                status = INVALID_OPERATION;
-            }
-        } else {
-            status = BAD_VALUE;
-        }
-    }
-    return status;
-}
-
-String8 AudioStreamOutDump::getParameters(const String8& keys)
-{
-    if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
-
-    AudioParameter param = AudioParameter(keys);
-    return param.toString();
-}
-
-status_t AudioStreamOutDump::dump(int fd, const Vector<String16>& args)
-{
-    if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
-    return NO_ERROR;
-}
-
-void AudioStreamOutDump::Close()
-{
-    if(mOutFile) {
-        fclose(mOutFile);
-        mOutFile = 0;
-    }
-}
-
-status_t AudioStreamOutDump::getRenderPosition(uint32_t *dspFrames)
-{
-    if (mFinalStream != 0 ) return mFinalStream->getRenderPosition(dspFrames);
-    return INVALID_OPERATION;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioStreamInDump::AudioStreamInDump(AudioDumpInterface *interface,
-                                        int id,
-                                        AudioStreamIn* finalStream,
-                                        uint32_t devices,
-                                        int format,
-                                        uint32_t channels,
-                                        uint32_t sampleRate)
-    : mInterface(interface), mId(id),
-      mSampleRate(sampleRate), mFormat(format), mChannels(channels), mDevice(devices),
-      mBufferSize(1024), mFinalStream(finalStream), mInFile(0)
-{
-    LOGV("AudioStreamInDump Constructor %p, mInterface %p, mFinalStream %p", this, mInterface, mFinalStream);
-}
-
-
-AudioStreamInDump::~AudioStreamInDump()
-{
-    Close();
-}
-
-ssize_t AudioStreamInDump::read(void* buffer, ssize_t bytes)
-{
-    if (mFinalStream) {
-        return mFinalStream->read(buffer, bytes);
-    }
-
-    usleep((bytes * 1000000) / frameSize() / sampleRate());
-
-    if(!mInFile) {
-        char name[255];
-        strcpy(name, "/sdcard/music/sine440");
-        if (channels() == AudioSystem::CHANNEL_IN_MONO) {
-            strcat(name, "_mo");
-        } else {
-            strcat(name, "_st");
-        }
-        if (format() == AudioSystem::PCM_16_BIT) {
-            strcat(name, "_16b");
-        } else {
-            strcat(name, "_8b");
-        }
-        if (sampleRate() < 16000) {
-            strcat(name, "_8k");
-        } else if (sampleRate() < 32000) {
-            strcat(name, "_22k");
-        } else if (sampleRate() < 48000) {
-            strcat(name, "_44k");
-        } else {
-            strcat(name, "_48k");
-        }
-        strcat(name, ".wav");
-        mInFile = fopen(name, "rb");
-        LOGV("Opening dump file %s, fh %p", name, mInFile);
-        if (mInFile) {
-            fseek(mInFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
-        }
-
-    }
-    if (mInFile) {
-        ssize_t bytesRead = fread(buffer, bytes, 1, mInFile);
-        if (bytesRead != bytes) {
-            fseek(mInFile, AUDIO_DUMP_WAVE_HDR_SIZE, SEEK_SET);
-            fread((uint8_t *)buffer+bytesRead, bytes-bytesRead, 1, mInFile);
-        }
-    }
-    return bytes;
-}
-
-status_t AudioStreamInDump::standby()
-{
-    LOGV("AudioStreamInDump standby(), mInFile %p, mFinalStream %p", mInFile, mFinalStream);
-
-    Close();
-    if (mFinalStream != 0 ) return mFinalStream->standby();
-    return NO_ERROR;
-}
-
-status_t AudioStreamInDump::setGain(float gain)
-{
-    if (mFinalStream != 0 ) return mFinalStream->setGain(gain);
-    return NO_ERROR;
-}
-
-uint32_t AudioStreamInDump::sampleRate() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->sampleRate();
-    return mSampleRate;
-}
-
-size_t AudioStreamInDump::bufferSize() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->bufferSize();
-    return mBufferSize;
-}
-
-uint32_t AudioStreamInDump::channels() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->channels();
-    return mChannels;
-}
-
-int AudioStreamInDump::format() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->format();
-    return mFormat;
-}
-
-status_t AudioStreamInDump::setParameters(const String8& keyValuePairs)
-{
-    LOGV("AudioStreamInDump::setParameters()");
-    if (mFinalStream != 0 ) return mFinalStream->setParameters(keyValuePairs);
-    return NO_ERROR;
-}
-
-String8 AudioStreamInDump::getParameters(const String8& keys)
-{
-    if (mFinalStream != 0 ) return mFinalStream->getParameters(keys);
-
-    AudioParameter param = AudioParameter(keys);
-    return param.toString();
-}
-
-unsigned int AudioStreamInDump::getInputFramesLost() const
-{
-    if (mFinalStream != 0 ) return mFinalStream->getInputFramesLost();
-    return 0;
-}
-
-status_t AudioStreamInDump::dump(int fd, const Vector<String16>& args)
-{
-    if (mFinalStream != 0 ) return mFinalStream->dump(fd, args);
-    return NO_ERROR;
-}
-
-void AudioStreamInDump::Close()
-{
-    if(mInFile) {
-        fclose(mInFile);
-        mInFile = 0;
-    }
-}
-}; // namespace android
diff --git a/libs/audioflinger/AudioDumpInterface.h b/libs/audioflinger/AudioDumpInterface.h
deleted file mode 100644
index 4c62b3e..0000000
--- a/libs/audioflinger/AudioDumpInterface.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/* //device/servers/AudioFlinger/AudioDumpInterface.h
-**
-** Copyright 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 ANDROID_AUDIO_DUMP_INTERFACE_H
-#define ANDROID_AUDIO_DUMP_INTERFACE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/String8.h>
-#include <utils/SortedVector.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-#define AUDIO_DUMP_WAVE_HDR_SIZE 44
-
-class AudioDumpInterface;
-
-class AudioStreamOutDump : public AudioStreamOut {
-public:
-                        AudioStreamOutDump(AudioDumpInterface *interface,
-                                            int id,
-                                            AudioStreamOut* finalStream,
-                                            uint32_t devices,
-                                            int format,
-                                            uint32_t channels,
-                                            uint32_t sampleRate);
-                        ~AudioStreamOutDump();
-
-    virtual ssize_t     write(const void* buffer, size_t bytes);
-    virtual uint32_t    sampleRate() const;
-    virtual size_t      bufferSize() const;
-    virtual uint32_t    channels() const;
-    virtual int         format() const;
-    virtual uint32_t    latency() const;
-    virtual status_t    setVolume(float left, float right);
-    virtual status_t    standby();
-    virtual status_t    setParameters(const String8& keyValuePairs);
-    virtual String8     getParameters(const String8& keys);
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    void                Close(void);
-    AudioStreamOut*     finalStream() { return mFinalStream; }
-    uint32_t            device() { return mDevice; }
-    int                 getId()  { return mId; }
-    virtual status_t    getRenderPosition(uint32_t *dspFrames);
-
-private:
-    AudioDumpInterface *mInterface;
-    int                  mId;
-    uint32_t mSampleRate;               //
-    uint32_t mFormat;                   //
-    uint32_t mChannels;                 // output configuration
-    uint32_t mLatency;                  //
-    uint32_t mDevice;                   // current device this output is routed to
-    size_t  mBufferSize;
-    AudioStreamOut      *mFinalStream;
-    FILE                *mOutFile;      // output file
-    int                 mFileCount;
-};
-
-class AudioStreamInDump : public AudioStreamIn {
-public:
-                        AudioStreamInDump(AudioDumpInterface *interface,
-                                            int id,
-                                            AudioStreamIn* finalStream,
-                                            uint32_t devices,
-                                            int format,
-                                            uint32_t channels,
-                                            uint32_t sampleRate);
-                        ~AudioStreamInDump();
-
-    virtual uint32_t    sampleRate() const;
-    virtual size_t      bufferSize() const;
-    virtual uint32_t    channels() const;
-    virtual int         format() const;
-
-    virtual status_t    setGain(float gain);
-    virtual ssize_t     read(void* buffer, ssize_t bytes);
-    virtual status_t    standby();
-    virtual status_t    setParameters(const String8& keyValuePairs);
-    virtual String8     getParameters(const String8& keys);
-    virtual unsigned int  getInputFramesLost() const;
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    void                Close(void);
-    AudioStreamIn*     finalStream() { return mFinalStream; }
-    uint32_t            device() { return mDevice; }
-
-private:
-    AudioDumpInterface *mInterface;
-    int                  mId;
-    uint32_t mSampleRate;               //
-    uint32_t mFormat;                   //
-    uint32_t mChannels;                 // output configuration
-    uint32_t mDevice;                   // current device this output is routed to
-    size_t  mBufferSize;
-    AudioStreamIn      *mFinalStream;
-    FILE                *mInFile;      // output file
-};
-
-class AudioDumpInterface : public AudioHardwareBase
-{
-
-public:
-                        AudioDumpInterface(AudioHardwareInterface* hw);
-    virtual AudioStreamOut* openOutputStream(
-                                uint32_t devices,
-                                int *format=0,
-                                uint32_t *channels=0,
-                                uint32_t *sampleRate=0,
-                                status_t *status=0);
-    virtual    void        closeOutputStream(AudioStreamOut* out);
-
-    virtual             ~AudioDumpInterface();
-
-    virtual status_t    initCheck()
-                            {return mFinalInterface->initCheck();}
-    virtual status_t    setVoiceVolume(float volume)
-                            {return mFinalInterface->setVoiceVolume(volume);}
-    virtual status_t    setMasterVolume(float volume)
-                            {return mFinalInterface->setMasterVolume(volume);}
-
-    // mic mute
-    virtual status_t    setMicMute(bool state)
-                            {return mFinalInterface->setMicMute(state);}
-    virtual status_t    getMicMute(bool* state)
-                            {return mFinalInterface->getMicMute(state);}
-
-    virtual status_t    setParameters(const String8& keyValuePairs);
-    virtual String8     getParameters(const String8& keys);
-
-    virtual AudioStreamIn* openInputStream(uint32_t devices, int *format, uint32_t *channels,
-            uint32_t *sampleRate, status_t *status, AudioSystem::audio_in_acoustics acoustics);
-    virtual    void        closeInputStream(AudioStreamIn* in);
-
-    virtual status_t    dump(int fd, const Vector<String16>& args) { return mFinalInterface->dumpState(fd, args); }
-
-            String8     fileName() const { return mFileName; }
-protected:
-
-    AudioHardwareInterface          *mFinalInterface;
-    SortedVector<AudioStreamOutDump *>    mOutputs;
-    bool                            mFirstHwOutput;
-    SortedVector<AudioStreamInDump *>    mInputs;
-    Mutex                           mLock;
-    String8                         mPolicyCommands;
-    String8                         mFileName;
-};
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_DUMP_INTERFACE_H
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
deleted file mode 100644
index 2414e8d..0000000
--- a/libs/audioflinger/AudioFlinger.cpp
+++ /dev/null
@@ -1,4055 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioFlinger.cpp
-**
-** 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.
-*/
-
-
-#define LOG_TAG "AudioFlinger"
-//#define LOG_NDEBUG 0
-
-#include <math.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <binder/IPCThreadState.h>
-#include <utils/String16.h>
-#include <utils/threads.h>
-
-#include <cutils/properties.h>
-
-#include <media/AudioTrack.h>
-#include <media/AudioRecord.h>
-
-#include <private/media/AudioTrackShared.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-
-#include "AudioMixer.h"
-#include "AudioFlinger.h"
-
-#ifdef WITH_A2DP
-#include "A2dpAudioInterface.h"
-#endif
-
-#ifdef LVMX
-#include "lifevibes.h"
-#endif
-
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-static const char* kDeadlockedString = "AudioFlinger may be deadlocked\n";
-static const char* kHardwareLockedString = "Hardware lock is taken\n";
-
-//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
-static const float MAX_GAIN = 4096.0f;
-
-// retry counts for buffer fill timeout
-// 50 * ~20msecs = 1 second
-static const int8_t kMaxTrackRetries = 50;
-static const int8_t kMaxTrackStartupRetries = 50;
-// allow less retry attempts on direct output thread.
-// direct outputs can be a scarce resource in audio hardware and should
-// be released as quickly as possible.
-static const int8_t kMaxTrackRetriesDirect = 2;
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 20000;
-
-static const nsecs_t kWarningThrottle = seconds(5);
-
-
-#define AUDIOFLINGER_SECURITY_ENABLED 1
-
-// ----------------------------------------------------------------------------
-
-static bool recordingAllowed() {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
-#if AUDIOFLINGER_SECURITY_ENABLED
-    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
-    bool ok = checkCallingPermission(String16("android.permission.RECORD_AUDIO"));
-    if (!ok) LOGE("Request requires android.permission.RECORD_AUDIO");
-    return ok;
-#else
-    if (!checkCallingPermission(String16("android.permission.RECORD_AUDIO")))
-        LOGW("WARNING: Need to add android.permission.RECORD_AUDIO to manifest");
-    return true;
-#endif
-}
-
-static bool settingsAllowed() {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
-#if AUDIOFLINGER_SECURITY_ENABLED
-    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
-    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
-    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
-    return ok;
-#else
-    if (!checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS")))
-        LOGW("WARNING: Need to add android.permission.MODIFY_AUDIO_SETTINGS to manifest");
-    return true;
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::AudioFlinger()
-    : BnAudioFlinger(),
-        mAudioHardware(0), mMasterVolume(1.0f), mMasterMute(false), mNextThreadId(0)
-{
-    mHardwareStatus = AUDIO_HW_IDLE;
-
-    mAudioHardware = AudioHardwareInterface::create();
-
-    mHardwareStatus = AUDIO_HW_INIT;
-    if (mAudioHardware->initCheck() == NO_ERROR) {
-        // open 16-bit output stream for s/w mixer
-
-        setMode(AudioSystem::MODE_NORMAL);
-
-        setMasterVolume(1.0f);
-        setMasterMute(false);
-    } else {
-        LOGE("Couldn't even initialize the stubbed audio hardware!");
-    }
-#ifdef LVMX
-    LifeVibes::init();
-#endif
-}
-
-AudioFlinger::~AudioFlinger()
-{
-    while (!mRecordThreads.isEmpty()) {
-        // closeInput() will remove first entry from mRecordThreads
-        closeInput(mRecordThreads.keyAt(0));
-    }
-    while (!mPlaybackThreads.isEmpty()) {
-        // closeOutput() will remove first entry from mPlaybackThreads
-        closeOutput(mPlaybackThreads.keyAt(0));
-    }
-    if (mAudioHardware) {
-        delete mAudioHardware;
-    }
-}
-
-
-
-status_t AudioFlinger::dumpClients(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    result.append("Clients:\n");
-    for (size_t i = 0; i < mClients.size(); ++i) {
-        wp<Client> wClient = mClients.valueAt(i);
-        if (wClient != 0) {
-            sp<Client> client = wClient.promote();
-            if (client != 0) {
-                snprintf(buffer, SIZE, "  pid: %d\n", client->pid());
-                result.append(buffer);
-            }
-        }
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-
-status_t AudioFlinger::dumpInternals(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    int hardwareStatus = mHardwareStatus;
-
-    snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::dumpPermissionDenial(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "Permission Denial: "
-            "can't dump AudioFlinger from pid=%d, uid=%d\n",
-            IPCThreadState::self()->getCallingPid(),
-            IPCThreadState::self()->getCallingUid());
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-static bool tryLock(Mutex& mutex)
-{
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleep);
-    }
-    return locked;
-}
-
-status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
-{
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        dumpPermissionDenial(fd, args);
-    } else {
-        // get state of hardware lock
-        bool hardwareLocked = tryLock(mHardwareLock);
-        if (!hardwareLocked) {
-            String8 result(kHardwareLockedString);
-            write(fd, result.string(), result.size());
-        } else {
-            mHardwareLock.unlock();
-        }
-
-        bool locked = tryLock(mLock);
-
-        // failed to lock - AudioFlinger is probably deadlocked
-        if (!locked) {
-            String8 result(kDeadlockedString);
-            write(fd, result.string(), result.size());
-        }
-
-        dumpClients(fd, args);
-        dumpInternals(fd, args);
-
-        // dump playback threads
-        for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-            mPlaybackThreads.valueAt(i)->dump(fd, args);
-        }
-
-        // dump record threads
-        for (size_t i = 0; i < mRecordThreads.size(); i++) {
-            mRecordThreads.valueAt(i)->dump(fd, args);
-        }
-
-        if (mAudioHardware) {
-            mAudioHardware->dumpState(fd, args);
-        }
-        if (locked) mLock.unlock();
-    }
-    return NO_ERROR;
-}
-
-
-// IAudioFlinger interface
-
-
-sp<IAudioTrack> AudioFlinger::createTrack(
-        pid_t pid,
-        int streamType,
-        uint32_t sampleRate,
-        int format,
-        int channelCount,
-        int frameCount,
-        uint32_t flags,
-        const sp<IMemory>& sharedBuffer,
-        int output,
-        status_t *status)
-{
-    sp<PlaybackThread::Track> track;
-    sp<TrackHandle> trackHandle;
-    sp<Client> client;
-    wp<Client> wclient;
-    status_t lStatus;
-
-    if (streamType >= AudioSystem::NUM_STREAM_TYPES) {
-        LOGE("invalid stream type");
-        lStatus = BAD_VALUE;
-        goto Exit;
-    }
-
-    {
-        Mutex::Autolock _l(mLock);
-        PlaybackThread *thread = checkPlaybackThread_l(output);
-        if (thread == NULL) {
-            LOGE("unknown output thread");
-            lStatus = BAD_VALUE;
-            goto Exit;
-        }
-
-        wclient = mClients.valueFor(pid);
-
-        if (wclient != NULL) {
-            client = wclient.promote();
-        } else {
-            client = new Client(this, pid);
-            mClients.add(pid, client);
-        }
-        track = thread->createTrack_l(client, streamType, sampleRate, format,
-                channelCount, frameCount, sharedBuffer, &lStatus);
-    }
-    if (lStatus == NO_ERROR) {
-        trackHandle = new TrackHandle(track);
-    } else {
-        // remove local strong reference to Client before deleting the Track so that the Client
-        // destructor is called by the TrackBase destructor with mLock held
-        client.clear();
-        track.clear();
-    }
-
-Exit:
-    if(status) {
-        *status = lStatus;
-    }
-    return trackHandle;
-}
-
-uint32_t AudioFlinger::sampleRate(int output) const
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-    if (thread == NULL) {
-        LOGW("sampleRate() unknown thread %d", output);
-        return 0;
-    }
-    return thread->sampleRate();
-}
-
-int AudioFlinger::channelCount(int output) const
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-    if (thread == NULL) {
-        LOGW("channelCount() unknown thread %d", output);
-        return 0;
-    }
-    return thread->channelCount();
-}
-
-int AudioFlinger::format(int output) const
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-    if (thread == NULL) {
-        LOGW("format() unknown thread %d", output);
-        return 0;
-    }
-    return thread->format();
-}
-
-size_t AudioFlinger::frameCount(int output) const
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-    if (thread == NULL) {
-        LOGW("frameCount() unknown thread %d", output);
-        return 0;
-    }
-    return thread->frameCount();
-}
-
-uint32_t AudioFlinger::latency(int output) const
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-    if (thread == NULL) {
-        LOGW("latency() unknown thread %d", output);
-        return 0;
-    }
-    return thread->latency();
-}
-
-status_t AudioFlinger::setMasterVolume(float value)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-    // when hw supports master volume, don't scale in sw mixer
-    AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
-    if (mAudioHardware->setMasterVolume(value) == NO_ERROR) {
-        value = 1.0f;
-    }
-    mHardwareStatus = AUDIO_HW_IDLE;
-
-    mMasterVolume = value;
-    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
-       mPlaybackThreads.valueAt(i)->setMasterVolume(value);
-
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::setMode(int mode)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES)) {
-        LOGW("Illegal value: setMode(%d)", mode);
-        return BAD_VALUE;
-    }
-
-    AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_HW_SET_MODE;
-    status_t ret = mAudioHardware->setMode(mode);
-#ifdef LVMX
-    if (NO_ERROR == ret) {
-        LifeVibes::setMode(mode);
-    }
-#endif
-    mHardwareStatus = AUDIO_HW_IDLE;
-    return ret;
-}
-
-status_t AudioFlinger::setMicMute(bool state)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-    AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_HW_SET_MIC_MUTE;
-    status_t ret = mAudioHardware->setMicMute(state);
-    mHardwareStatus = AUDIO_HW_IDLE;
-    return ret;
-}
-
-bool AudioFlinger::getMicMute() const
-{
-    bool state = AudioSystem::MODE_INVALID;
-    mHardwareStatus = AUDIO_HW_GET_MIC_MUTE;
-    mAudioHardware->getMicMute(&state);
-    mHardwareStatus = AUDIO_HW_IDLE;
-    return state;
-}
-
-status_t AudioFlinger::setMasterMute(bool muted)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-    mMasterMute = muted;
-    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
-       mPlaybackThreads.valueAt(i)->setMasterMute(muted);
-
-    return NO_ERROR;
-}
-
-float AudioFlinger::masterVolume() const
-{
-    return mMasterVolume;
-}
-
-bool AudioFlinger::masterMute() const
-{
-    return mMasterMute;
-}
-
-status_t AudioFlinger::setStreamVolume(int stream, float value, int output)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-    if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
-        return BAD_VALUE;
-    }
-
-    AutoMutex lock(mLock);
-    PlaybackThread *thread = NULL;
-    if (output) {
-        thread = checkPlaybackThread_l(output);
-        if (thread == NULL) {
-            return BAD_VALUE;
-        }
-    }
-
-    mStreamTypes[stream].volume = value;
-
-    if (thread == NULL) {
-        for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
-           mPlaybackThreads.valueAt(i)->setStreamVolume(stream, value);
-        }
-    } else {
-        thread->setStreamVolume(stream, value);
-    }
-
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::setStreamMute(int stream, bool muted)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-    if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES ||
-        uint32_t(stream) == AudioSystem::ENFORCED_AUDIBLE) {
-        return BAD_VALUE;
-    }
-
-    mStreamTypes[stream].mute = muted;
-    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
-       mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
-
-    return NO_ERROR;
-}
-
-float AudioFlinger::streamVolume(int stream, int output) const
-{
-    if (stream < 0 || uint32_t(stream) >= AudioSystem::NUM_STREAM_TYPES) {
-        return 0.0f;
-    }
-
-    AutoMutex lock(mLock);
-    float volume;
-    if (output) {
-        PlaybackThread *thread = checkPlaybackThread_l(output);
-        if (thread == NULL) {
-            return 0.0f;
-        }
-        volume = thread->streamVolume(stream);
-    } else {
-        volume = mStreamTypes[stream].volume;
-    }
-
-    return volume;
-}
-
-bool AudioFlinger::streamMute(int stream) const
-{
-    if (stream < 0 || stream >= (int)AudioSystem::NUM_STREAM_TYPES) {
-        return true;
-    }
-
-    return mStreamTypes[stream].mute;
-}
-
-bool AudioFlinger::isStreamActive(int stream) const
-{
-    Mutex::Autolock _l(mLock);
-    for (uint32_t i = 0; i < mPlaybackThreads.size(); i++) {
-        if (mPlaybackThreads.valueAt(i)->isStreamActive(stream)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-status_t AudioFlinger::setParameters(int ioHandle, const String8& keyValuePairs)
-{
-    status_t result;
-
-    LOGV("setParameters(): io %d, keyvalue %s, tid %d, calling tid %d",
-            ioHandle, keyValuePairs.string(), gettid(), IPCThreadState::self()->getCallingPid());
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-#ifdef LVMX
-    AudioParameter param = AudioParameter(keyValuePairs);
-    LifeVibes::setParameters(ioHandle,keyValuePairs);
-    String8 key = String8(AudioParameter::keyRouting);
-    int device;
-    if (NO_ERROR != param.getInt(key, device)) {
-        device = -1;
-    }
-
-    key = String8(LifevibesTag);
-    String8 value;
-    int musicEnabled = -1;
-    if (NO_ERROR == param.get(key, value)) {
-        if (value == LifevibesEnable) {
-            musicEnabled = 1;
-        } else if (value == LifevibesDisable) {
-            musicEnabled = 0;
-        }
-    }
-#endif
-
-    // ioHandle == 0 means the parameters are global to the audio hardware interface
-    if (ioHandle == 0) {
-        AutoMutex lock(mHardwareLock);
-        mHardwareStatus = AUDIO_SET_PARAMETER;
-        result = mAudioHardware->setParameters(keyValuePairs);
-#ifdef LVMX
-        if ((NO_ERROR == result) && (musicEnabled != -1)) {
-            LifeVibes::enableMusic((bool) musicEnabled);
-        }
-#endif
-        mHardwareStatus = AUDIO_HW_IDLE;
-        return result;
-    }
-
-    // hold a strong ref on thread in case closeOutput() or closeInput() is called
-    // and the thread is exited once the lock is released
-    sp<ThreadBase> thread;
-    {
-        Mutex::Autolock _l(mLock);
-        thread = checkPlaybackThread_l(ioHandle);
-        if (thread == NULL) {
-            thread = checkRecordThread_l(ioHandle);
-        }
-    }
-    if (thread != NULL) {
-        result = thread->setParameters(keyValuePairs);
-#ifdef LVMX
-        if ((NO_ERROR == result) && (device != -1)) {
-            LifeVibes::setDevice(LifeVibes::threadIdToAudioOutputType(thread->id()), device);
-        }
-#endif
-        return result;
-    }
-    return BAD_VALUE;
-}
-
-String8 AudioFlinger::getParameters(int ioHandle, const String8& keys)
-{
-//    LOGV("getParameters() io %d, keys %s, tid %d, calling tid %d",
-//            ioHandle, keys.string(), gettid(), IPCThreadState::self()->getCallingPid());
-
-    if (ioHandle == 0) {
-        return mAudioHardware->getParameters(keys);
-    }
-
-    Mutex::Autolock _l(mLock);
-
-    PlaybackThread *playbackThread = checkPlaybackThread_l(ioHandle);
-    if (playbackThread != NULL) {
-        return playbackThread->getParameters(keys);
-    }
-    RecordThread *recordThread = checkRecordThread_l(ioHandle);
-    if (recordThread != NULL) {
-        return recordThread->getParameters(keys);
-    }
-    return String8("");
-}
-
-size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
-    return mAudioHardware->getInputBufferSize(sampleRate, format, channelCount);
-}
-
-unsigned int AudioFlinger::getInputFramesLost(int ioHandle)
-{
-    if (ioHandle == 0) {
-        return 0;
-    }
-
-    Mutex::Autolock _l(mLock);
-
-    RecordThread *recordThread = checkRecordThread_l(ioHandle);
-    if (recordThread != NULL) {
-        return recordThread->getInputFramesLost();
-    }
-    return 0;
-}
-
-status_t AudioFlinger::setVoiceVolume(float value)
-{
-    // check calling permissions
-    if (!settingsAllowed()) {
-        return PERMISSION_DENIED;
-    }
-
-    AutoMutex lock(mHardwareLock);
-    mHardwareStatus = AUDIO_SET_VOICE_VOLUME;
-    status_t ret = mAudioHardware->setVoiceVolume(value);
-    mHardwareStatus = AUDIO_HW_IDLE;
-
-    return ret;
-}
-
-status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output)
-{
-    status_t status;
-
-    Mutex::Autolock _l(mLock);
-
-    PlaybackThread *playbackThread = checkPlaybackThread_l(output);
-    if (playbackThread != NULL) {
-        return playbackThread->getRenderPosition(halFrames, dspFrames);
-    }
-
-    return BAD_VALUE;
-}
-
-void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client)
-{
-
-    LOGV("registerClient() %p, tid %d, calling tid %d", client.get(), gettid(), IPCThreadState::self()->getCallingPid());
-    Mutex::Autolock _l(mLock);
-
-    sp<IBinder> binder = client->asBinder();
-    if (mNotificationClients.indexOf(binder) < 0) {
-        LOGV("Adding notification client %p", binder.get());
-        binder->linkToDeath(this);
-        mNotificationClients.add(binder);
-    }
-
-    // the config change is always sent from playback or record threads to avoid deadlock
-    // with AudioSystem::gLock
-    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-        mPlaybackThreads.valueAt(i)->sendConfigEvent(AudioSystem::OUTPUT_OPENED);
-    }
-
-    for (size_t i = 0; i < mRecordThreads.size(); i++) {
-        mRecordThreads.valueAt(i)->sendConfigEvent(AudioSystem::INPUT_OPENED);
-    }
-}
-
-void AudioFlinger::binderDied(const wp<IBinder>& who) {
-
-    LOGV("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
-    Mutex::Autolock _l(mLock);
-
-    IBinder *binder = who.unsafe_get();
-
-    if (binder != NULL) {
-        int index = mNotificationClients.indexOf(binder);
-        if (index >= 0) {
-            LOGV("Removing notification client %p", binder);
-            mNotificationClients.removeAt(index);
-        }
-    }
-}
-
-// audioConfigChanged_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::audioConfigChanged_l(int event, int ioHandle, void *param2) {
-    size_t size = mNotificationClients.size();
-    for (size_t i = 0; i < size; i++) {
-        sp<IBinder> binder = mNotificationClients.itemAt(i);
-        LOGV("audioConfigChanged_l() Notifying change to client %p", binder.get());
-        sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient> (binder);
-        client->ioConfigChanged(event, ioHandle, param2);
-    }
-}
-
-// removeClient_l() must be called with AudioFlinger::mLock held
-void AudioFlinger::removeClient_l(pid_t pid)
-{
-    LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
-    mClients.removeItem(pid);
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id)
-    :   Thread(false),
-        mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
-        mFormat(0), mFrameSize(1), mStandby(false), mId(id), mExiting(false)
-{
-}
-
-AudioFlinger::ThreadBase::~ThreadBase()
-{
-    mParamCond.broadcast();
-    mNewParameters.clear();
-}
-
-void AudioFlinger::ThreadBase::exit()
-{
-    // keep a strong ref on ourself so that we wont get
-    // destroyed in the middle of requestExitAndWait()
-    sp <ThreadBase> strongMe = this;
-
-    LOGV("ThreadBase::exit");
-    {
-        AutoMutex lock(&mLock);
-        mExiting = true;
-        requestExit();
-        mWaitWorkCV.signal();
-    }
-    requestExitAndWait();
-}
-
-uint32_t AudioFlinger::ThreadBase::sampleRate() const
-{
-    return mSampleRate;
-}
-
-int AudioFlinger::ThreadBase::channelCount() const
-{
-    return mChannelCount;
-}
-
-int AudioFlinger::ThreadBase::format() const
-{
-    return mFormat;
-}
-
-size_t AudioFlinger::ThreadBase::frameCount() const
-{
-    return mFrameCount;
-}
-
-status_t AudioFlinger::ThreadBase::setParameters(const String8& keyValuePairs)
-{
-    status_t status;
-
-    LOGV("ThreadBase::setParameters() %s", keyValuePairs.string());
-    Mutex::Autolock _l(mLock);
-
-    mNewParameters.add(keyValuePairs);
-    mWaitWorkCV.signal();
-    // wait condition with timeout in case the thread loop has exited
-    // before the request could be processed
-    if (mParamCond.waitRelative(mLock, seconds(2)) == NO_ERROR) {
-        status = mParamStatus;
-        mWaitWorkCV.signal();
-    } else {
-        status = TIMED_OUT;
-    }
-    return status;
-}
-
-void AudioFlinger::ThreadBase::sendConfigEvent(int event, int param)
-{
-    Mutex::Autolock _l(mLock);
-    sendConfigEvent_l(event, param);
-}
-
-// sendConfigEvent_l() must be called with ThreadBase::mLock held
-void AudioFlinger::ThreadBase::sendConfigEvent_l(int event, int param)
-{
-    ConfigEvent *configEvent = new ConfigEvent();
-    configEvent->mEvent = event;
-    configEvent->mParam = param;
-    mConfigEvents.add(configEvent);
-    LOGV("sendConfigEvent() num events %d event %d, param %d", mConfigEvents.size(), event, param);
-    mWaitWorkCV.signal();
-}
-
-void AudioFlinger::ThreadBase::processConfigEvents()
-{
-    mLock.lock();
-    while(!mConfigEvents.isEmpty()) {
-        LOGV("processConfigEvents() remaining events %d", mConfigEvents.size());
-        ConfigEvent *configEvent = mConfigEvents[0];
-        mConfigEvents.removeAt(0);
-        // release mLock because audioConfigChanged() will lock AudioFlinger mLock
-        // before calling Audioflinger::audioConfigChanged_l() thus creating
-        // potential cross deadlock between AudioFlinger::mLock and mLock
-        mLock.unlock();
-        audioConfigChanged(configEvent->mEvent, configEvent->mParam);
-        delete configEvent;
-        mLock.lock();
-    }
-    mLock.unlock();
-}
-
-status_t AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    bool locked = tryLock(mLock);
-    if (!locked) {
-        snprintf(buffer, SIZE, "thread %p maybe dead locked\n", this);
-        write(fd, buffer, strlen(buffer));
-    }
-
-    snprintf(buffer, SIZE, "standby: %d\n", mStandby);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Sample rate: %d\n", mSampleRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Frame count: %d\n", mFrameCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Channel Count: %d\n", mChannelCount);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Format: %d\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Frame size: %d\n", mFrameSize);
-    result.append(buffer);
-
-    snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
-    result.append(buffer);
-    result.append(" Index Command");
-    for (size_t i = 0; i < mNewParameters.size(); ++i) {
-        snprintf(buffer, SIZE, "\n %02d    ", i);
-        result.append(buffer);
-        result.append(mNewParameters[i]);
-    }
-
-    snprintf(buffer, SIZE, "\n\nPending config events: \n");
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Index event param\n");
-    result.append(buffer);
-    for (size_t i = 0; i < mConfigEvents.size(); i++) {
-        snprintf(buffer, SIZE, " %02d    %02d    %d\n", i, mConfigEvents[i]->mEvent, mConfigEvents[i]->mParam);
-        result.append(buffer);
-    }
-    result.append("\n");
-
-    write(fd, result.string(), result.size());
-
-    if (locked) {
-        mLock.unlock();
-    }
-    return NO_ERROR;
-}
-
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
-    :   ThreadBase(audioFlinger, id),
-        mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
-        mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
-{
-    readOutputParameters();
-
-    mMasterVolume = mAudioFlinger->masterVolume();
-    mMasterMute = mAudioFlinger->masterMute();
-
-    for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
-        mStreamTypes[stream].volume = mAudioFlinger->streamVolumeInternal(stream);
-        mStreamTypes[stream].mute = mAudioFlinger->streamMute(stream);
-    }
-    // notify client processes that a new input has been opened
-    sendConfigEvent(AudioSystem::OUTPUT_OPENED);
-}
-
-AudioFlinger::PlaybackThread::~PlaybackThread()
-{
-    delete [] mMixBuffer;
-}
-
-status_t AudioFlinger::PlaybackThread::dump(int fd, const Vector<String16>& args)
-{
-    dumpInternals(fd, args);
-    dumpTracks(fd, args);
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "Output thread %p tracks\n", this);
-    result.append(buffer);
-    result.append("   Name Clien Typ Fmt Chn Buf  S M F SRate  LeftV RighV Serv     User\n");
-    for (size_t i = 0; i < mTracks.size(); ++i) {
-        sp<Track> track = mTracks[i];
-        if (track != 0) {
-            track->dump(buffer, SIZE);
-            result.append(buffer);
-        }
-    }
-
-    snprintf(buffer, SIZE, "Output thread %p active tracks\n", this);
-    result.append(buffer);
-    result.append("   Name Clien Typ Fmt Chn Buf  S M F SRate  LeftV RighV Serv     User\n");
-    for (size_t i = 0; i < mActiveTracks.size(); ++i) {
-        wp<Track> wTrack = mActiveTracks[i];
-        if (wTrack != 0) {
-            sp<Track> track = wTrack.promote();
-            if (track != 0) {
-                track->dump(buffer, SIZE);
-                result.append(buffer);
-            }
-        }
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n", ns2ms(systemTime() - mLastWriteTime));
-    result.append(buffer);
-    snprintf(buffer, SIZE, "total writes: %d\n", mNumWrites);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "delayed writes: %d\n", mNumDelayedWrites);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "blocked in write: %d\n", mInWrite);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "suspend count: %d\n", mSuspended);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    dumpBase(fd, args);
-
-    return NO_ERROR;
-}
-
-// Thread virtuals
-status_t AudioFlinger::PlaybackThread::readyToRun()
-{
-    if (mSampleRate == 0) {
-        LOGE("No working audio driver found.");
-        return NO_INIT;
-    }
-    LOGI("AudioFlinger's thread %p ready to run", this);
-    return NO_ERROR;
-}
-
-void AudioFlinger::PlaybackThread::onFirstRef()
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "Playback Thread %p", this);
-
-    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
-}
-
-// PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
-sp<AudioFlinger::PlaybackThread::Track>  AudioFlinger::PlaybackThread::createTrack_l(
-        const sp<AudioFlinger::Client>& client,
-        int streamType,
-        uint32_t sampleRate,
-        int format,
-        int channelCount,
-        int frameCount,
-        const sp<IMemory>& sharedBuffer,
-        status_t *status)
-{
-    sp<Track> track;
-    status_t lStatus;
-
-    if (mType == DIRECT) {
-        if (sampleRate != mSampleRate || format != mFormat || channelCount != mChannelCount) {
-            LOGE("createTrack_l() Bad parameter:  sampleRate %d format %d, channelCount %d for output %p",
-                 sampleRate, format, channelCount, mOutput);
-            lStatus = BAD_VALUE;
-            goto Exit;
-        }
-    } else {
-        // Resampler implementation limits input sampling rate to 2 x output sampling rate.
-        if (sampleRate > mSampleRate*2) {
-            LOGE("Sample rate out of range: %d mSampleRate %d", sampleRate, mSampleRate);
-            lStatus = BAD_VALUE;
-            goto Exit;
-        }
-    }
-
-    if (mOutput == 0) {
-        LOGE("Audio driver not initialized.");
-        lStatus = NO_INIT;
-        goto Exit;
-    }
-
-    { // scope for mLock
-        Mutex::Autolock _l(mLock);
-        track = new Track(this, client, streamType, sampleRate, format,
-                channelCount, frameCount, sharedBuffer);
-        if (track->getCblk() == NULL || track->name() < 0) {
-            lStatus = NO_MEMORY;
-            goto Exit;
-        }
-        mTracks.add(track);
-    }
-    lStatus = NO_ERROR;
-
-Exit:
-    if(status) {
-        *status = lStatus;
-    }
-    return track;
-}
-
-uint32_t AudioFlinger::PlaybackThread::latency() const
-{
-    if (mOutput) {
-        return mOutput->latency();
-    }
-    else {
-        return 0;
-    }
-}
-
-status_t AudioFlinger::PlaybackThread::setMasterVolume(float value)
-{
-#ifdef LVMX
-    int audioOutputType = LifeVibes::getMixerType(mId, mType);
-    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
-        LifeVibes::setMasterVolume(audioOutputType, value);
-    }
-#endif
-    mMasterVolume = value;
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::PlaybackThread::setMasterMute(bool muted)
-{
-#ifdef LVMX
-    int audioOutputType = LifeVibes::getMixerType(mId, mType);
-    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
-        LifeVibes::setMasterMute(audioOutputType, muted);
-    }
-#endif
-    mMasterMute = muted;
-    return NO_ERROR;
-}
-
-float AudioFlinger::PlaybackThread::masterVolume() const
-{
-    return mMasterVolume;
-}
-
-bool AudioFlinger::PlaybackThread::masterMute() const
-{
-    return mMasterMute;
-}
-
-status_t AudioFlinger::PlaybackThread::setStreamVolume(int stream, float value)
-{
-#ifdef LVMX
-    int audioOutputType = LifeVibes::getMixerType(mId, mType);
-    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
-        LifeVibes::setStreamVolume(audioOutputType, stream, value);
-    }
-#endif
-    mStreamTypes[stream].volume = value;
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::PlaybackThread::setStreamMute(int stream, bool muted)
-{
-#ifdef LVMX
-    int audioOutputType = LifeVibes::getMixerType(mId, mType);
-    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
-        LifeVibes::setStreamMute(audioOutputType, stream, muted);
-    }
-#endif
-    mStreamTypes[stream].mute = muted;
-    return NO_ERROR;
-}
-
-float AudioFlinger::PlaybackThread::streamVolume(int stream) const
-{
-    return mStreamTypes[stream].volume;
-}
-
-bool AudioFlinger::PlaybackThread::streamMute(int stream) const
-{
-    return mStreamTypes[stream].mute;
-}
-
-bool AudioFlinger::PlaybackThread::isStreamActive(int stream) const
-{
-    Mutex::Autolock _l(mLock);
-    size_t count = mActiveTracks.size();
-    for (size_t i = 0 ; i < count ; ++i) {
-        sp<Track> t = mActiveTracks[i].promote();
-        if (t == 0) continue;
-        Track* const track = t.get();
-        if (t->type() == stream)
-            return true;
-    }
-    return false;
-}
-
-// addTrack_l() must be called with ThreadBase::mLock held
-status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track)
-{
-    status_t status = ALREADY_EXISTS;
-
-    // set retry count for buffer fill
-    track->mRetryCount = kMaxTrackStartupRetries;
-    if (mActiveTracks.indexOf(track) < 0) {
-        // the track is newly added, make sure it fills up all its
-        // buffers before playing. This is to ensure the client will
-        // effectively get the latency it requested.
-        track->mFillingUpStatus = Track::FS_FILLING;
-        track->mResetDone = false;
-        mActiveTracks.add(track);
-        status = NO_ERROR;
-    }
-
-    LOGV("mWaitWorkCV.broadcast");
-    mWaitWorkCV.broadcast();
-
-    return status;
-}
-
-// destroyTrack_l() must be called with ThreadBase::mLock held
-void AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track)
-{
-    track->mState = TrackBase::TERMINATED;
-    if (mActiveTracks.indexOf(track) < 0) {
-        mTracks.remove(track);
-        deleteTrackName_l(track->name());
-    }
-}
-
-String8 AudioFlinger::PlaybackThread::getParameters(const String8& keys)
-{
-    return mOutput->getParameters(keys);
-}
-
-void AudioFlinger::PlaybackThread::audioConfigChanged(int event, int param) {
-    AudioSystem::OutputDescriptor desc;
-    void *param2 = 0;
-
-    LOGV("PlaybackThread::audioConfigChanged, thread %p, event %d, param %d", this, event, param);
-
-    switch (event) {
-    case AudioSystem::OUTPUT_OPENED:
-    case AudioSystem::OUTPUT_CONFIG_CHANGED:
-        desc.channels = mChannelCount;
-        desc.samplingRate = mSampleRate;
-        desc.format = mFormat;
-        desc.frameCount = mFrameCount;
-        desc.latency = latency();
-        param2 = &desc;
-        break;
-
-    case AudioSystem::STREAM_CONFIG_CHANGED:
-        param2 = &param;
-    case AudioSystem::OUTPUT_CLOSED:
-    default:
-        break;
-    }
-    Mutex::Autolock _l(mAudioFlinger->mLock);
-    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
-}
-
-void AudioFlinger::PlaybackThread::readOutputParameters()
-{
-    mSampleRate = mOutput->sampleRate();
-    mChannelCount = AudioSystem::popCount(mOutput->channels());
-
-    mFormat = mOutput->format();
-    mFrameSize = mOutput->frameSize();
-    mFrameCount = mOutput->bufferSize() / mFrameSize;
-
-    // FIXME - Current mixer implementation only supports stereo output: Always
-    // Allocate a stereo buffer even if HW output is mono.
-    if (mMixBuffer != NULL) delete mMixBuffer;
-    mMixBuffer = new int16_t[mFrameCount * 2];
-    memset(mMixBuffer, 0, mFrameCount * 2 * sizeof(int16_t));
-}
-
-status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
-{
-    if (halFrames == 0 || dspFrames == 0) {
-        return BAD_VALUE;
-    }
-    if (mOutput == 0) {
-        return INVALID_OPERATION;
-    }
-    *halFrames = mBytesWritten/mOutput->frameSize();
-
-    return mOutput->getRenderPosition(dspFrames);
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
-    :   PlaybackThread(audioFlinger, output, id),
-        mAudioMixer(0)
-{
-    mType = PlaybackThread::MIXER;
-    mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
-
-    // FIXME - Current mixer implementation only supports stereo output
-    if (mChannelCount == 1) {
-        LOGE("Invalid audio hardware channel count");
-    }
-}
-
-AudioFlinger::MixerThread::~MixerThread()
-{
-    delete mAudioMixer;
-}
-
-bool AudioFlinger::MixerThread::threadLoop()
-{
-    int16_t* curBuf = mMixBuffer;
-    Vector< sp<Track> > tracksToRemove;
-    uint32_t mixerStatus = MIXER_IDLE;
-    nsecs_t standbyTime = systemTime();
-    size_t mixBufferSize = mFrameCount * mFrameSize;
-    // FIXME: Relaxed timing because of a certain device that can't meet latency
-    // Should be reduced to 2x after the vendor fixes the driver issue
-    nsecs_t maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
-    nsecs_t lastWarning = 0;
-    bool longStandbyExit = false;
-    uint32_t activeSleepTime = activeSleepTimeUs();
-    uint32_t idleSleepTime = idleSleepTimeUs();
-    uint32_t sleepTime = idleSleepTime;
-
-    while (!exitPending())
-    {
-        processConfigEvents();
-
-        mixerStatus = MIXER_IDLE;
-        { // scope for mLock
-
-            Mutex::Autolock _l(mLock);
-
-            if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount * mFrameSize;
-                // FIXME: Relaxed timing because of a certain device that can't meet latency
-                // Should be reduced to 2x after the vendor fixes the driver issue
-                maxPeriod = seconds(mFrameCount) / mSampleRate * 3;
-                activeSleepTime = activeSleepTimeUs();
-                idleSleepTime = idleSleepTimeUs();
-            }
-
-            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
-            // put audio hardware into standby after short delay
-            if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
-                        mSuspended) {
-                if (!mStandby) {
-                    LOGV("Audio hardware entering standby, mixer %p, mSuspended %d\n", this, mSuspended);
-                    mOutput->standby();
-                    mStandby = true;
-                    mBytesWritten = 0;
-                }
-
-                if (!activeTracks.size() && mConfigEvents.isEmpty()) {
-                    // we're about to wait, flush the binder command buffer
-                    IPCThreadState::self()->flushCommands();
-
-                    if (exitPending()) break;
-
-                    // wait until we have something to do...
-                    LOGV("MixerThread %p TID %d going to sleep\n", this, gettid());
-                    mWaitWorkCV.wait(mLock);
-                    LOGV("MixerThread %p TID %d waking up\n", this, gettid());
-
-                    if (mMasterMute == false) {
-                        char value[PROPERTY_VALUE_MAX];
-                        property_get("ro.audio.silent", value, "0");
-                        if (atoi(value)) {
-                            LOGD("Silence is golden");
-                            setMasterMute(true);
-                        }
-                    }
-
-                    standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    sleepTime = idleSleepTime;
-                    continue;
-                }
-            }
-
-            mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
-       }
-
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
-            // mix buffers...
-            mAudioMixer->process(curBuf);
-            sleepTime = 0;
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
-        } else {
-            // If no tracks are ready, sleep once for the duration of an output
-            // buffer size, then write 0s to the output
-            if (sleepTime == 0) {
-                if (mixerStatus == MIXER_TRACKS_ENABLED) {
-                    sleepTime = activeSleepTime;
-                } else {
-                    sleepTime = idleSleepTime;
-                }
-            } else if (mBytesWritten != 0 ||
-                       (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)) {
-                memset (curBuf, 0, mixBufferSize);
-                sleepTime = 0;
-                LOGV_IF((mBytesWritten == 0 && (mixerStatus == MIXER_TRACKS_ENABLED && longStandbyExit)), "anticipated start");
-            }
-        }
-
-        if (mSuspended) {
-            sleepTime = idleSleepTime;
-        }
-        // sleepTime == 0 means we must write to audio hardware
-        if (sleepTime == 0) {
-            mLastWriteTime = systemTime();
-            mInWrite = true;
-            mBytesWritten += mixBufferSize;
-#ifdef LVMX
-            int audioOutputType = LifeVibes::getMixerType(mId, mType);
-            if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType)) {
-               LifeVibes::process(audioOutputType, curBuf, mixBufferSize);
-            }
-#endif
-            int bytesWritten = (int)mOutput->write(curBuf, mixBufferSize);
-            if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
-            mNumWrites++;
-            mInWrite = false;
-            nsecs_t now = systemTime();
-            nsecs_t delta = now - mLastWriteTime;
-            if (delta > maxPeriod) {
-                mNumDelayedWrites++;
-                if ((now - lastWarning) > kWarningThrottle) {
-                    LOGW("write blocked for %llu msecs, %d delayed writes, thread %p",
-                            ns2ms(delta), mNumDelayedWrites, this);
-                    lastWarning = now;
-                }
-                if (mStandby) {
-                    longStandbyExit = true;
-                }
-            }
-            mStandby = false;
-        } else {
-            usleep(sleepTime);
-        }
-
-        // finally let go of all our tracks, without the lock held
-        // since we can't guarantee the destructors won't acquire that
-        // same lock.
-        tracksToRemove.clear();
-    }
-
-    if (!mStandby) {
-        mOutput->standby();
-    }
-
-    LOGV("MixerThread %p exiting", this);
-    return false;
-}
-
-// prepareTracks_l() must be called with ThreadBase::mLock held
-uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove)
-{
-
-    uint32_t mixerStatus = MIXER_IDLE;
-    // find out which tracks need to be processed
-    size_t count = activeTracks.size();
-
-    float masterVolume = mMasterVolume;
-    bool  masterMute = mMasterMute;
-
-#ifdef LVMX
-    bool tracksConnectedChanged = false;
-    bool stateChanged = false;
-
-    int audioOutputType = LifeVibes::getMixerType(mId, mType);
-    if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType))
-    {
-        int activeTypes = 0;
-        for (size_t i=0 ; i<count ; i++) {
-            sp<Track> t = activeTracks[i].promote();
-            if (t == 0) continue;
-            Track* const track = t.get();
-            int iTracktype=track->type();
-            activeTypes |= 1<<track->type();
-        }
-        LifeVibes::computeVolumes(audioOutputType, activeTypes, tracksConnectedChanged, stateChanged, masterVolume, masterMute);
-    }
-#endif
-
-    for (size_t i=0 ; i<count ; i++) {
-        sp<Track> t = activeTracks[i].promote();
-        if (t == 0) continue;
-
-        Track* const track = t.get();
-        audio_track_cblk_t* cblk = track->cblk();
-
-        // The first time a track is added we wait
-        // for all its buffers to be filled before processing it
-        mAudioMixer->setActiveTrack(track->name());
-        if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
-                !track->isPaused() && !track->isTerminated())
-        {
-            //LOGV("track %d u=%08x, s=%08x [OK] on thread %p", track->name(), cblk->user, cblk->server, this);
-
-            // compute volume for this track
-            int16_t left, right;
-            if (track->isMuted() || masterMute || track->isPausing() ||
-                mStreamTypes[track->type()].mute) {
-                left = right = 0;
-                if (track->isPausing()) {
-                    track->setPaused();
-                }
-            } else {
-                // read original volumes with volume control
-                float typeVolume = mStreamTypes[track->type()].volume;
-#ifdef LVMX
-                bool streamMute=false;
-                // read the volume from the LivesVibes audio engine.
-                if (LifeVibes::audioOutputTypeIsLifeVibes(audioOutputType))
-                {
-                    LifeVibes::getStreamVolumes(audioOutputType, track->type(), &typeVolume, &streamMute);
-                    if (streamMute) {
-                        typeVolume = 0;
-                    }
-                }
-#endif
-                float v = masterVolume * typeVolume;
-                float v_clamped = v * cblk->volume[0];
-                if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
-                left = int16_t(v_clamped);
-                v_clamped = v * cblk->volume[1];
-                if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
-                right = int16_t(v_clamped);
-            }
-
-            // XXX: these things DON'T need to be done each time
-            mAudioMixer->setBufferProvider(track);
-            mAudioMixer->enable(AudioMixer::MIXING);
-
-            int param = AudioMixer::VOLUME;
-            if (track->mFillingUpStatus == Track::FS_FILLED) {
-                // no ramp for the first volume setting
-                track->mFillingUpStatus = Track::FS_ACTIVE;
-                if (track->mState == TrackBase::RESUMING) {
-                    track->mState = TrackBase::ACTIVE;
-                    param = AudioMixer::RAMP_VOLUME;
-                }
-            } else if (cblk->server != 0) {
-                // If the track is stopped before the first frame was mixed,
-                // do not apply ramp
-                param = AudioMixer::RAMP_VOLUME;
-            }
-#ifdef LVMX
-            if ( tracksConnectedChanged || stateChanged )
-            {
-                 // only do the ramp when the volume is changed by the user / application
-                 param = AudioMixer::VOLUME;
-            }
-#endif
-            mAudioMixer->setParameter(param, AudioMixer::VOLUME0, left);
-            mAudioMixer->setParameter(param, AudioMixer::VOLUME1, right);
-            mAudioMixer->setParameter(
-                AudioMixer::TRACK,
-                AudioMixer::FORMAT, track->format());
-            mAudioMixer->setParameter(
-                AudioMixer::TRACK,
-                AudioMixer::CHANNEL_COUNT, track->channelCount());
-            mAudioMixer->setParameter(
-                AudioMixer::RESAMPLE,
-                AudioMixer::SAMPLE_RATE,
-                int(cblk->sampleRate));
-
-            // reset retry count
-            track->mRetryCount = kMaxTrackRetries;
-            mixerStatus = MIXER_TRACKS_READY;
-        } else {
-            //LOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", track->name(), cblk->user, cblk->server, this);
-            if (track->isStopped()) {
-                track->reset();
-            }
-            if (track->isTerminated() || track->isStopped() || track->isPaused()) {
-                // We have consumed all the buffers of this track.
-                // Remove it from the list of active tracks.
-                tracksToRemove->add(track);
-                mAudioMixer->disable(AudioMixer::MIXING);
-            } else {
-                // No buffers for this track. Give it a few chances to
-                // fill a buffer, then remove it from active list.
-                if (--(track->mRetryCount) <= 0) {
-                    LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
-                    tracksToRemove->add(track);
-                } else if (mixerStatus != MIXER_TRACKS_READY) {
-                    mixerStatus = MIXER_TRACKS_ENABLED;
-                }
-
-                mAudioMixer->disable(AudioMixer::MIXING);
-            }
-        }
-    }
-
-    // remove all the tracks that need to be...
-    count = tracksToRemove->size();
-    if (UNLIKELY(count)) {
-        for (size_t i=0 ; i<count ; i++) {
-            const sp<Track>& track = tracksToRemove->itemAt(i);
-            mActiveTracks.remove(track);
-            if (track->isTerminated()) {
-                mTracks.remove(track);
-                deleteTrackName_l(track->mName);
-            }
-        }
-    }
-
-    return mixerStatus;
-}
-
-void AudioFlinger::MixerThread::getTracks(
-        SortedVector < sp<Track> >& tracks,
-        SortedVector < wp<Track> >& activeTracks,
-        int streamType)
-{
-    LOGV ("MixerThread::getTracks() mixer %p, mTracks.size %d, mActiveTracks.size %d", this,  mTracks.size(), mActiveTracks.size());
-    Mutex::Autolock _l(mLock);
-    size_t size = mTracks.size();
-    for (size_t i = 0; i < size; i++) {
-        sp<Track> t = mTracks[i];
-        if (t->type() == streamType) {
-            tracks.add(t);
-            int j = mActiveTracks.indexOf(t);
-            if (j >= 0) {
-                t = mActiveTracks[j].promote();
-                if (t != NULL) {
-                    activeTracks.add(t);
-                }
-            }
-        }
-    }
-
-    size = activeTracks.size();
-    for (size_t i = 0; i < size; i++) {
-        mActiveTracks.remove(activeTracks[i]);
-    }
-
-    size = tracks.size();
-    for (size_t i = 0; i < size; i++) {
-        sp<Track> t = tracks[i];
-        mTracks.remove(t);
-        deleteTrackName_l(t->name());
-    }
-}
-
-void AudioFlinger::MixerThread::putTracks(
-        SortedVector < sp<Track> >& tracks,
-        SortedVector < wp<Track> >& activeTracks)
-{
-    LOGV ("MixerThread::putTracks() mixer %p, tracks.size %d, activeTracks.size %d", this,  tracks.size(), activeTracks.size());
-    Mutex::Autolock _l(mLock);
-    size_t size = tracks.size();
-    for (size_t i = 0; i < size ; i++) {
-        sp<Track> t = tracks[i];
-        int name = getTrackName_l();
-
-        if (name < 0) return;
-
-        t->mName = name;
-        t->mThread = this;
-        mTracks.add(t);
-
-        int j = activeTracks.indexOf(t);
-        if (j >= 0) {
-            mActiveTracks.add(t);
-            // force buffer refilling and no ramp volume when the track is mixed for the first time
-            t->mFillingUpStatus = Track::FS_FILLING;
-        }
-    }
-}
-
-// getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::MixerThread::getTrackName_l()
-{
-    return mAudioMixer->getTrackName();
-}
-
-// deleteTrackName_l() must be called with ThreadBase::mLock held
-void AudioFlinger::MixerThread::deleteTrackName_l(int name)
-{
-    LOGV("remove track (%d) and delete from mixer", name);
-    mAudioMixer->deleteTrackName(name);
-}
-
-// checkForNewParameters_l() must be called with ThreadBase::mLock held
-bool AudioFlinger::MixerThread::checkForNewParameters_l()
-{
-    bool reconfig = false;
-
-    while (!mNewParameters.isEmpty()) {
-        status_t status = NO_ERROR;
-        String8 keyValuePair = mNewParameters[0];
-        AudioParameter param = AudioParameter(keyValuePair);
-        int value;
-
-        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
-            reconfig = true;
-        }
-        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
-            if (value != AudioSystem::PCM_16_BIT) {
-                status = BAD_VALUE;
-            } else {
-                reconfig = true;
-            }
-        }
-        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
-            if (value != AudioSystem::CHANNEL_OUT_STEREO) {
-                status = BAD_VALUE;
-            } else {
-                reconfig = true;
-            }
-        }
-        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
-            // do not accept frame count changes if tracks are open as the track buffer
-            // size depends on frame count and correct behavior would not be garantied
-            // if frame count is changed after track creation
-            if (!mTracks.isEmpty()) {
-                status = INVALID_OPERATION;
-            } else {
-                reconfig = true;
-            }
-        }
-        if (status == NO_ERROR) {
-            status = mOutput->setParameters(keyValuePair);
-            if (!mStandby && status == INVALID_OPERATION) {
-               mOutput->standby();
-               mStandby = true;
-               mBytesWritten = 0;
-               status = mOutput->setParameters(keyValuePair);
-            }
-            if (status == NO_ERROR && reconfig) {
-                delete mAudioMixer;
-                readOutputParameters();
-                mAudioMixer = new AudioMixer(mFrameCount, mSampleRate);
-                for (size_t i = 0; i < mTracks.size() ; i++) {
-                    int name = getTrackName_l();
-                    if (name < 0) break;
-                    mTracks[i]->mName = name;
-                    // limit track sample rate to 2 x new output sample rate
-                    if (mTracks[i]->mCblk->sampleRate > 2 * sampleRate()) {
-                        mTracks[i]->mCblk->sampleRate = 2 * sampleRate();
-                    }
-                }
-                sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
-            }
-        }
-
-        mNewParameters.removeAt(0);
-
-        mParamStatus = status;
-        mParamCond.signal();
-        mWaitWorkCV.wait(mLock);
-    }
-    return reconfig;
-}
-
-status_t AudioFlinger::MixerThread::dumpInternals(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    PlaybackThread::dumpInternals(fd, args);
-
-    snprintf(buffer, SIZE, "AudioMixer tracks: %08x\n", mAudioMixer->trackNames());
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-uint32_t AudioFlinger::MixerThread::activeSleepTimeUs()
-{
-    return (uint32_t)(mOutput->latency() * 1000) / 2;
-}
-
-uint32_t AudioFlinger::MixerThread::idleSleepTimeUs()
-{
-    return (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000;
-}
-
-// ----------------------------------------------------------------------------
-AudioFlinger::DirectOutputThread::DirectOutputThread(const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id)
-    :   PlaybackThread(audioFlinger, output, id),
-    mLeftVolume (1.0), mRightVolume(1.0)
-{
-    mType = PlaybackThread::DIRECT;
-}
-
-AudioFlinger::DirectOutputThread::~DirectOutputThread()
-{
-}
-
-
-bool AudioFlinger::DirectOutputThread::threadLoop()
-{
-    uint32_t mixerStatus = MIXER_IDLE;
-    sp<Track> trackToRemove;
-    sp<Track> activeTrack;
-    nsecs_t standbyTime = systemTime();
-    int8_t *curBuf;
-    size_t mixBufferSize = mFrameCount*mFrameSize;
-    uint32_t activeSleepTime = activeSleepTimeUs();
-    uint32_t idleSleepTime = idleSleepTimeUs();
-    uint32_t sleepTime = idleSleepTime;
-    // use shorter standby delay as on normal output to release
-    // hardware resources as soon as possible
-    nsecs_t standbyDelay = microseconds(activeSleepTime*2);
-
-
-    while (!exitPending())
-    {
-        processConfigEvents();
-
-        mixerStatus = MIXER_IDLE;
-
-        { // scope for the mLock
-
-            Mutex::Autolock _l(mLock);
-
-            if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount*mFrameSize;
-                activeSleepTime = activeSleepTimeUs();
-                idleSleepTime = idleSleepTimeUs();
-                standbyDelay = microseconds(activeSleepTime*2);
-            }
-
-            // put audio hardware into standby after short delay
-            if UNLIKELY((!mActiveTracks.size() && systemTime() > standbyTime) ||
-                        mSuspended) {
-                // wait until we have something to do...
-                if (!mStandby) {
-                    LOGV("Audio hardware entering standby, mixer %p\n", this);
-                    mOutput->standby();
-                    mStandby = true;
-                    mBytesWritten = 0;
-                }
-
-                if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
-                    // we're about to wait, flush the binder command buffer
-                    IPCThreadState::self()->flushCommands();
-
-                    if (exitPending()) break;
-
-                    LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid());
-                    mWaitWorkCV.wait(mLock);
-                    LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid());
-
-                    if (mMasterMute == false) {
-                        char value[PROPERTY_VALUE_MAX];
-                        property_get("ro.audio.silent", value, "0");
-                        if (atoi(value)) {
-                            LOGD("Silence is golden");
-                            setMasterMute(true);
-                        }
-                    }
-
-                    standbyTime = systemTime() + standbyDelay;
-                    sleepTime = idleSleepTime;
-                    continue;
-                }
-            }
-
-            // find out which tracks need to be processed
-            if (mActiveTracks.size() != 0) {
-                sp<Track> t = mActiveTracks[0].promote();
-                if (t == 0) continue;
-
-                Track* const track = t.get();
-                audio_track_cblk_t* cblk = track->cblk();
-
-                // The first time a track is added we wait
-                // for all its buffers to be filled before processing it
-                if (cblk->framesReady() && (track->isReady() || track->isStopped()) &&
-                        !track->isPaused() && !track->isTerminated())
-                {
-                    //LOGV("track %d u=%08x, s=%08x [OK]", track->name(), cblk->user, cblk->server);
-
-                    // compute volume for this track
-                    float left, right;
-                    if (track->isMuted() || mMasterMute || track->isPausing() ||
-                        mStreamTypes[track->type()].mute) {
-                        left = right = 0;
-                        if (track->isPausing()) {
-                            track->setPaused();
-                        }
-                    } else {
-                        float typeVolume = mStreamTypes[track->type()].volume;
-                        float v = mMasterVolume * typeVolume;
-                        float v_clamped = v * cblk->volume[0];
-                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
-                        left = v_clamped/MAX_GAIN;
-                        v_clamped = v * cblk->volume[1];
-                        if (v_clamped > MAX_GAIN) v_clamped = MAX_GAIN;
-                        right = v_clamped/MAX_GAIN;
-                    }
-
-                    if (left != mLeftVolume || right != mRightVolume) {
-                        mOutput->setVolume(left, right);
-                        left = mLeftVolume;
-                        right = mRightVolume;
-                    }
-
-                    if (track->mFillingUpStatus == Track::FS_FILLED) {
-                        track->mFillingUpStatus = Track::FS_ACTIVE;
-                        if (track->mState == TrackBase::RESUMING) {
-                            track->mState = TrackBase::ACTIVE;
-                        }
-                    }
-
-                    // reset retry count
-                    track->mRetryCount = kMaxTrackRetriesDirect;
-                    activeTrack = t;
-                    mixerStatus = MIXER_TRACKS_READY;
-                } else {
-                    //LOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
-                    if (track->isStopped()) {
-                        track->reset();
-                    }
-                    if (track->isTerminated() || track->isStopped() || track->isPaused()) {
-                        // We have consumed all the buffers of this track.
-                        // Remove it from the list of active tracks.
-                        trackToRemove = track;
-                    } else {
-                        // No buffers for this track. Give it a few chances to
-                        // fill a buffer, then remove it from active list.
-                        if (--(track->mRetryCount) <= 0) {
-                            LOGV("BUFFER TIMEOUT: remove(%d) from active list", track->name());
-                            trackToRemove = track;
-                        } else {
-                            mixerStatus = MIXER_TRACKS_ENABLED;
-                        }
-                    }
-                }
-            }
-
-            // remove all the tracks that need to be...
-            if (UNLIKELY(trackToRemove != 0)) {
-                mActiveTracks.remove(trackToRemove);
-                if (trackToRemove->isTerminated()) {
-                    mTracks.remove(trackToRemove);
-                    deleteTrackName_l(trackToRemove->mName);
-                }
-            }
-       }
-
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
-            AudioBufferProvider::Buffer buffer;
-            size_t frameCount = mFrameCount;
-            curBuf = (int8_t *)mMixBuffer;
-            // output audio to hardware
-            while(frameCount) {
-                buffer.frameCount = frameCount;
-                activeTrack->getNextBuffer(&buffer);
-                if (UNLIKELY(buffer.raw == 0)) {
-                    memset(curBuf, 0, frameCount * mFrameSize);
-                    break;
-                }
-                memcpy(curBuf, buffer.raw, buffer.frameCount * mFrameSize);
-                frameCount -= buffer.frameCount;
-                curBuf += buffer.frameCount * mFrameSize;
-                activeTrack->releaseBuffer(&buffer);
-            }
-            sleepTime = 0;
-            standbyTime = systemTime() + standbyDelay;
-        } else {
-            if (sleepTime == 0) {
-                if (mixerStatus == MIXER_TRACKS_ENABLED) {
-                    sleepTime = activeSleepTime;
-                } else {
-                    sleepTime = idleSleepTime;
-                }
-            } else if (mBytesWritten != 0 && AudioSystem::isLinearPCM(mFormat)) {
-                memset (mMixBuffer, 0, mFrameCount * mFrameSize);
-                sleepTime = 0;
-            }
-        }
-
-        if (mSuspended) {
-            sleepTime = idleSleepTime;
-        }
-        // sleepTime == 0 means we must write to audio hardware
-        if (sleepTime == 0) {
-            mLastWriteTime = systemTime();
-            mInWrite = true;
-            mBytesWritten += mixBufferSize;
-            int bytesWritten = (int)mOutput->write(mMixBuffer, mixBufferSize);
-            if (bytesWritten < 0) mBytesWritten -= mixBufferSize;
-            mNumWrites++;
-            mInWrite = false;
-            mStandby = false;
-        } else {
-            usleep(sleepTime);
-        }
-
-        // finally let go of removed track, without the lock held
-        // since we can't guarantee the destructors won't acquire that
-        // same lock.
-        trackToRemove.clear();
-        activeTrack.clear();
-    }
-
-    if (!mStandby) {
-        mOutput->standby();
-    }
-
-    LOGV("DirectOutputThread %p exiting", this);
-    return false;
-}
-
-// getTrackName_l() must be called with ThreadBase::mLock held
-int AudioFlinger::DirectOutputThread::getTrackName_l()
-{
-    return 0;
-}
-
-// deleteTrackName_l() must be called with ThreadBase::mLock held
-void AudioFlinger::DirectOutputThread::deleteTrackName_l(int name)
-{
-}
-
-// checkForNewParameters_l() must be called with ThreadBase::mLock held
-bool AudioFlinger::DirectOutputThread::checkForNewParameters_l()
-{
-    bool reconfig = false;
-
-    while (!mNewParameters.isEmpty()) {
-        status_t status = NO_ERROR;
-        String8 keyValuePair = mNewParameters[0];
-        AudioParameter param = AudioParameter(keyValuePair);
-        int value;
-
-        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
-            // do not accept frame count changes if tracks are open as the track buffer
-            // size depends on frame count and correct behavior would not be garantied
-            // if frame count is changed after track creation
-            if (!mTracks.isEmpty()) {
-                status = INVALID_OPERATION;
-            } else {
-                reconfig = true;
-            }
-        }
-        if (status == NO_ERROR) {
-            status = mOutput->setParameters(keyValuePair);
-            if (!mStandby && status == INVALID_OPERATION) {
-               mOutput->standby();
-               mStandby = true;
-               mBytesWritten = 0;
-               status = mOutput->setParameters(keyValuePair);
-            }
-            if (status == NO_ERROR && reconfig) {
-                readOutputParameters();
-                sendConfigEvent_l(AudioSystem::OUTPUT_CONFIG_CHANGED);
-            }
-        }
-
-        mNewParameters.removeAt(0);
-
-        mParamStatus = status;
-        mParamCond.signal();
-        mWaitWorkCV.wait(mLock);
-    }
-    return reconfig;
-}
-
-uint32_t AudioFlinger::DirectOutputThread::activeSleepTimeUs()
-{
-    uint32_t time;
-    if (AudioSystem::isLinearPCM(mFormat)) {
-        time = (uint32_t)(mOutput->latency() * 1000) / 2;
-    } else {
-        time = 10000;
-    }
-    return time;
-}
-
-uint32_t AudioFlinger::DirectOutputThread::idleSleepTimeUs()
-{
-    uint32_t time;
-    if (AudioSystem::isLinearPCM(mFormat)) {
-        time = (uint32_t)((mFrameCount * 1000) / mSampleRate) * 1000;
-    } else {
-        time = 10000;
-    }
-    return time;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::DuplicatingThread::DuplicatingThread(const sp<AudioFlinger>& audioFlinger, AudioFlinger::MixerThread* mainThread, int id)
-    :   MixerThread(audioFlinger, mainThread->getOutput(), id), mWaitTimeMs(UINT_MAX)
-{
-    mType = PlaybackThread::DUPLICATING;
-    addOutputTrack(mainThread);
-}
-
-AudioFlinger::DuplicatingThread::~DuplicatingThread()
-{
-    for (size_t i = 0; i < mOutputTracks.size(); i++) {
-        mOutputTracks[i]->destroy();
-    }
-    mOutputTracks.clear();
-}
-
-bool AudioFlinger::DuplicatingThread::threadLoop()
-{
-    int16_t* curBuf = mMixBuffer;
-    Vector< sp<Track> > tracksToRemove;
-    uint32_t mixerStatus = MIXER_IDLE;
-    nsecs_t standbyTime = systemTime();
-    size_t mixBufferSize = mFrameCount*mFrameSize;
-    SortedVector< sp<OutputTrack> > outputTracks;
-    uint32_t writeFrames = 0;
-    uint32_t activeSleepTime = activeSleepTimeUs();
-    uint32_t idleSleepTime = idleSleepTimeUs();
-    uint32_t sleepTime = idleSleepTime;
-
-    while (!exitPending())
-    {
-        processConfigEvents();
-
-        mixerStatus = MIXER_IDLE;
-        { // scope for the mLock
-
-            Mutex::Autolock _l(mLock);
-
-            if (checkForNewParameters_l()) {
-                mixBufferSize = mFrameCount*mFrameSize;
-                updateWaitTime();
-                activeSleepTime = activeSleepTimeUs();
-                idleSleepTime = idleSleepTimeUs();
-            }
-
-            const SortedVector< wp<Track> >& activeTracks = mActiveTracks;
-
-            for (size_t i = 0; i < mOutputTracks.size(); i++) {
-                outputTracks.add(mOutputTracks[i]);
-            }
-
-            // put audio hardware into standby after short delay
-            if UNLIKELY((!activeTracks.size() && systemTime() > standbyTime) ||
-                         mSuspended) {
-                if (!mStandby) {
-                    for (size_t i = 0; i < outputTracks.size(); i++) {
-                        outputTracks[i]->stop();
-                    }
-                    mStandby = true;
-                    mBytesWritten = 0;
-                }
-
-                if (!activeTracks.size() && mConfigEvents.isEmpty()) {
-                    // we're about to wait, flush the binder command buffer
-                    IPCThreadState::self()->flushCommands();
-                    outputTracks.clear();
-
-                    if (exitPending()) break;
-
-                    LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid());
-                    mWaitWorkCV.wait(mLock);
-                    LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
-                    if (mMasterMute == false) {
-                        char value[PROPERTY_VALUE_MAX];
-                        property_get("ro.audio.silent", value, "0");
-                        if (atoi(value)) {
-                            LOGD("Silence is golden");
-                            setMasterMute(true);
-                        }
-                    }
-
-                    standbyTime = systemTime() + kStandbyTimeInNsecs;
-                    sleepTime = idleSleepTime;
-                    continue;
-                }
-            }
-
-            mixerStatus = prepareTracks_l(activeTracks, &tracksToRemove);
-        }
-
-        if (LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
-            // mix buffers...
-            if (outputsReady(outputTracks)) {
-                mAudioMixer->process(curBuf);
-            } else {
-                memset(curBuf, 0, mixBufferSize);
-            }
-            sleepTime = 0;
-            writeFrames = mFrameCount;
-        } else {
-            if (sleepTime == 0) {
-                if (mixerStatus == MIXER_TRACKS_ENABLED) {
-                    sleepTime = activeSleepTime;
-                } else {
-                    sleepTime = idleSleepTime;
-                }
-            } else if (mBytesWritten != 0) {
-                // flush remaining overflow buffers in output tracks
-                for (size_t i = 0; i < outputTracks.size(); i++) {
-                    if (outputTracks[i]->isActive()) {
-                        sleepTime = 0;
-                        writeFrames = 0;
-                        break;
-                    }
-                }
-            }
-        }
-
-        if (mSuspended) {
-            sleepTime = idleSleepTime;
-        }
-        // sleepTime == 0 means we must write to audio hardware
-        if (sleepTime == 0) {
-            standbyTime = systemTime() + kStandbyTimeInNsecs;
-            for (size_t i = 0; i < outputTracks.size(); i++) {
-                outputTracks[i]->write(curBuf, writeFrames);
-            }
-            mStandby = false;
-            mBytesWritten += mixBufferSize;
-        } else {
-            usleep(sleepTime);
-        }
-
-        // finally let go of all our tracks, without the lock held
-        // since we can't guarantee the destructors won't acquire that
-        // same lock.
-        tracksToRemove.clear();
-        outputTracks.clear();
-    }
-
-    return false;
-}
-
-void AudioFlinger::DuplicatingThread::addOutputTrack(MixerThread *thread)
-{
-    int frameCount = (3 * mFrameCount * mSampleRate) / thread->sampleRate();
-    OutputTrack *outputTrack = new OutputTrack((ThreadBase *)thread,
-                                            this,
-                                            mSampleRate,
-                                            mFormat,
-                                            mChannelCount,
-                                            frameCount);
-    if (outputTrack->cblk() != NULL) {
-        thread->setStreamVolume(AudioSystem::NUM_STREAM_TYPES, 1.0f);
-        mOutputTracks.add(outputTrack);
-        LOGV("addOutputTrack() track %p, on thread %p", outputTrack, thread);
-        updateWaitTime();
-    }
-}
-
-void AudioFlinger::DuplicatingThread::removeOutputTrack(MixerThread *thread)
-{
-    Mutex::Autolock _l(mLock);
-    for (size_t i = 0; i < mOutputTracks.size(); i++) {
-        if (mOutputTracks[i]->thread() == (ThreadBase *)thread) {
-            mOutputTracks[i]->destroy();
-            mOutputTracks.removeAt(i);
-            updateWaitTime();
-            return;
-        }
-    }
-    LOGV("removeOutputTrack(): unkonwn thread: %p", thread);
-}
-
-void AudioFlinger::DuplicatingThread::updateWaitTime()
-{
-    mWaitTimeMs = UINT_MAX;
-    for (size_t i = 0; i < mOutputTracks.size(); i++) {
-        sp<ThreadBase> strong = mOutputTracks[i]->thread().promote();
-        if (strong != NULL) {
-            uint32_t waitTimeMs = (strong->frameCount() * 2 * 1000) / strong->sampleRate();
-            if (waitTimeMs < mWaitTimeMs) {
-                mWaitTimeMs = waitTimeMs;
-            }
-        }
-    }
-}
-
-
-bool AudioFlinger::DuplicatingThread::outputsReady(SortedVector< sp<OutputTrack> > &outputTracks)
-{
-    for (size_t i = 0; i < outputTracks.size(); i++) {
-        sp <ThreadBase> thread = outputTracks[i]->thread().promote();
-        if (thread == 0) {
-            LOGW("DuplicatingThread::outputsReady() could not promote thread on output track %p", outputTracks[i].get());
-            return false;
-        }
-        PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-        if (playbackThread->standby() && !playbackThread->isSuspended()) {
-            LOGV("DuplicatingThread output track %p on thread %p Not Ready", outputTracks[i].get(), thread.get());
-            return false;
-        }
-    }
-    return true;
-}
-
-uint32_t AudioFlinger::DuplicatingThread::activeSleepTimeUs()
-{
-    return (mWaitTimeMs * 1000) / 2;
-}
-
-// ----------------------------------------------------------------------------
-
-// TrackBase constructor must be called with AudioFlinger::mLock held
-AudioFlinger::ThreadBase::TrackBase::TrackBase(
-            const wp<ThreadBase>& thread,
-            const sp<Client>& client,
-            uint32_t sampleRate,
-            int format,
-            int channelCount,
-            int frameCount,
-            uint32_t flags,
-            const sp<IMemory>& sharedBuffer)
-    :   RefBase(),
-        mThread(thread),
-        mClient(client),
-        mCblk(0),
-        mFrameCount(0),
-        mState(IDLE),
-        mClientTid(-1),
-        mFormat(format),
-        mFlags(flags & ~SYSTEM_FLAGS_MASK)
-{
-    LOGV_IF(sharedBuffer != 0, "sharedBuffer: %p, size: %d", sharedBuffer->pointer(), sharedBuffer->size());
-
-    // LOGD("Creating track with %d buffers @ %d bytes", bufferCount, bufferSize);
-   size_t size = sizeof(audio_track_cblk_t);
-   size_t bufferSize = frameCount*channelCount*sizeof(int16_t);
-   if (sharedBuffer == 0) {
-       size += bufferSize;
-   }
-
-   if (client != NULL) {
-        mCblkMemory = client->heap()->allocate(size);
-        if (mCblkMemory != 0) {
-            mCblk = static_cast<audio_track_cblk_t *>(mCblkMemory->pointer());
-            if (mCblk) { // construct the shared structure in-place.
-                new(mCblk) audio_track_cblk_t();
-                // clear all buffers
-                mCblk->frameCount = frameCount;
-                mCblk->sampleRate = sampleRate;
-                mCblk->channels = (uint8_t)channelCount;
-                if (sharedBuffer == 0) {
-                    mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
-                    memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
-                    // Force underrun condition to avoid false underrun callback until first data is
-                    // written to buffer
-                    mCblk->flowControlFlag = 1;
-                } else {
-                    mBuffer = sharedBuffer->pointer();
-                }
-                mBufferEnd = (uint8_t *)mBuffer + bufferSize;
-            }
-        } else {
-            LOGE("not enough memory for AudioTrack size=%u", size);
-            client->heap()->dump("AudioTrack");
-            return;
-        }
-   } else {
-       mCblk = (audio_track_cblk_t *)(new uint8_t[size]);
-       if (mCblk) { // construct the shared structure in-place.
-           new(mCblk) audio_track_cblk_t();
-           // clear all buffers
-           mCblk->frameCount = frameCount;
-           mCblk->sampleRate = sampleRate;
-           mCblk->channels = (uint8_t)channelCount;
-           mBuffer = (char*)mCblk + sizeof(audio_track_cblk_t);
-           memset(mBuffer, 0, frameCount*channelCount*sizeof(int16_t));
-           // Force underrun condition to avoid false underrun callback until first data is
-           // written to buffer
-           mCblk->flowControlFlag = 1;
-           mBufferEnd = (uint8_t *)mBuffer + bufferSize;
-       }
-   }
-}
-
-AudioFlinger::ThreadBase::TrackBase::~TrackBase()
-{
-    if (mCblk) {
-        mCblk->~audio_track_cblk_t();   // destroy our shared-structure.
-        if (mClient == NULL) {
-            delete mCblk;
-        }
-    }
-    mCblkMemory.clear();            // and free the shared memory
-    if (mClient != NULL) {
-        Mutex::Autolock _l(mClient->audioFlinger()->mLock);
-        mClient.clear();
-    }
-}
-
-void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
-{
-    buffer->raw = 0;
-    mFrameCount = buffer->frameCount;
-    step();
-    buffer->frameCount = 0;
-}
-
-bool AudioFlinger::ThreadBase::TrackBase::step() {
-    bool result;
-    audio_track_cblk_t* cblk = this->cblk();
-
-    result = cblk->stepServer(mFrameCount);
-    if (!result) {
-        LOGV("stepServer failed acquiring cblk mutex");
-        mFlags |= STEPSERVER_FAILED;
-    }
-    return result;
-}
-
-void AudioFlinger::ThreadBase::TrackBase::reset() {
-    audio_track_cblk_t* cblk = this->cblk();
-
-    cblk->user = 0;
-    cblk->server = 0;
-    cblk->userBase = 0;
-    cblk->serverBase = 0;
-    mFlags &= (uint32_t)(~SYSTEM_FLAGS_MASK);
-    LOGV("TrackBase::reset");
-}
-
-sp<IMemory> AudioFlinger::ThreadBase::TrackBase::getCblk() const
-{
-    return mCblkMemory;
-}
-
-int AudioFlinger::ThreadBase::TrackBase::sampleRate() const {
-    return (int)mCblk->sampleRate;
-}
-
-int AudioFlinger::ThreadBase::TrackBase::channelCount() const {
-    return (int)mCblk->channels;
-}
-
-void* AudioFlinger::ThreadBase::TrackBase::getBuffer(uint32_t offset, uint32_t frames) const {
-    audio_track_cblk_t* cblk = this->cblk();
-    int8_t *bufferStart = (int8_t *)mBuffer + (offset-cblk->serverBase)*cblk->frameSize;
-    int8_t *bufferEnd = bufferStart + frames * cblk->frameSize;
-
-    // Check validity of returned pointer in case the track control block would have been corrupted.
-    if (bufferStart < mBuffer || bufferStart > bufferEnd || bufferEnd > mBufferEnd ||
-        ((unsigned long)bufferStart & (unsigned long)(cblk->frameSize - 1))) {
-        LOGE("TrackBase::getBuffer buffer out of range:\n    start: %p, end %p , mBuffer %p mBufferEnd %p\n    \
-                server %d, serverBase %d, user %d, userBase %d, channels %d",
-                bufferStart, bufferEnd, mBuffer, mBufferEnd,
-                cblk->server, cblk->serverBase, cblk->user, cblk->userBase, cblk->channels);
-        return 0;
-    }
-
-    return bufferStart;
-}
-
-// ----------------------------------------------------------------------------
-
-// Track constructor must be called with AudioFlinger::mLock and ThreadBase::mLock held
-AudioFlinger::PlaybackThread::Track::Track(
-            const wp<ThreadBase>& thread,
-            const sp<Client>& client,
-            int streamType,
-            uint32_t sampleRate,
-            int format,
-            int channelCount,
-            int frameCount,
-            const sp<IMemory>& sharedBuffer)
-    :   TrackBase(thread, client, sampleRate, format, channelCount, frameCount, 0, sharedBuffer),
-    mMute(false), mSharedBuffer(sharedBuffer), mName(-1)
-{
-    if (mCblk != NULL) {
-        sp<ThreadBase> baseThread = thread.promote();
-        if (baseThread != 0) {
-            PlaybackThread *playbackThread = (PlaybackThread *)baseThread.get();
-            mName = playbackThread->getTrackName_l();
-        }
-        LOGV("Track constructor name %d, calling thread %d", mName, IPCThreadState::self()->getCallingPid());
-        if (mName < 0) {
-            LOGE("no more track names available");
-        }
-        mVolume[0] = 1.0f;
-        mVolume[1] = 1.0f;
-        mStreamType = streamType;
-        // NOTE: audio_track_cblk_t::frameSize for 8 bit PCM data is based on a sample size of
-        // 16 bit because data is converted to 16 bit before being stored in buffer by AudioTrack
-        mCblk->frameSize = AudioSystem::isLinearPCM(format) ? channelCount * sizeof(int16_t) : sizeof(int8_t);
-    }
-}
-
-AudioFlinger::PlaybackThread::Track::~Track()
-{
-    LOGV("PlaybackThread::Track destructor");
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        Mutex::Autolock _l(thread->mLock);
-        mState = TERMINATED;
-    }
-}
-
-void AudioFlinger::PlaybackThread::Track::destroy()
-{
-    // NOTE: destroyTrack_l() can remove a strong reference to this Track
-    // by removing it from mTracks vector, so there is a risk that this Tracks's
-    // desctructor is called. As the destructor needs to lock mLock,
-    // we must acquire a strong reference on this Track before locking mLock
-    // here so that the destructor is called only when exiting this function.
-    // On the other hand, as long as Track::destroy() is only called by
-    // TrackHandle destructor, the TrackHandle still holds a strong ref on
-    // this Track with its member mTrack.
-    sp<Track> keep(this);
-    { // scope for mLock
-        sp<ThreadBase> thread = mThread.promote();
-        if (thread != 0) {
-            if (!isOutputTrack()) {
-                if (mState == ACTIVE || mState == RESUMING) {
-                    AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
-                }
-                AudioSystem::releaseOutput(thread->id());
-            }
-            Mutex::Autolock _l(thread->mLock);
-            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-            playbackThread->destroyTrack_l(this);
-        }
-    }
-}
-
-void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
-{
-    snprintf(buffer, size, "  %5d %5d %3u %3u %3u %04u %1d %1d %1d %5u %5u %5u  %08x %08x\n",
-            mName - AudioMixer::TRACK0,
-            (mClient == NULL) ? getpid() : mClient->pid(),
-            mStreamType,
-            mFormat,
-            mCblk->channels,
-            mFrameCount,
-            mState,
-            mMute,
-            mFillingUpStatus,
-            mCblk->sampleRate,
-            mCblk->volume[0],
-            mCblk->volume[1],
-            mCblk->server,
-            mCblk->user);
-}
-
-status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
-{
-     audio_track_cblk_t* cblk = this->cblk();
-     uint32_t framesReady;
-     uint32_t framesReq = buffer->frameCount;
-
-     // Check if last stepServer failed, try to step now
-     if (mFlags & TrackBase::STEPSERVER_FAILED) {
-         if (!step())  goto getNextBuffer_exit;
-         LOGV("stepServer recovered");
-         mFlags &= ~TrackBase::STEPSERVER_FAILED;
-     }
-
-     framesReady = cblk->framesReady();
-
-     if (LIKELY(framesReady)) {
-        uint32_t s = cblk->server;
-        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
-
-        bufferEnd = (cblk->loopEnd < bufferEnd) ? cblk->loopEnd : bufferEnd;
-        if (framesReq > framesReady) {
-            framesReq = framesReady;
-        }
-        if (s + framesReq > bufferEnd) {
-            framesReq = bufferEnd - s;
-        }
-
-         buffer->raw = getBuffer(s, framesReq);
-         if (buffer->raw == 0) goto getNextBuffer_exit;
-
-         buffer->frameCount = framesReq;
-        return NO_ERROR;
-     }
-
-getNextBuffer_exit:
-     buffer->raw = 0;
-     buffer->frameCount = 0;
-     LOGV("getNextBuffer() no more data for track %d on thread %p", mName, mThread.unsafe_get());
-     return NOT_ENOUGH_DATA;
-}
-
-bool AudioFlinger::PlaybackThread::Track::isReady() const {
-    if (mFillingUpStatus != FS_FILLING) return true;
-
-    if (mCblk->framesReady() >= mCblk->frameCount ||
-        mCblk->forceReady) {
-        mFillingUpStatus = FS_FILLED;
-        mCblk->forceReady = 0;
-        return true;
-    }
-    return false;
-}
-
-status_t AudioFlinger::PlaybackThread::Track::start()
-{
-    status_t status = NO_ERROR;
-    LOGV("start(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        Mutex::Autolock _l(thread->mLock);
-        int state = mState;
-        // here the track could be either new, or restarted
-        // in both cases "unstop" the track
-        if (mState == PAUSED) {
-            mState = TrackBase::RESUMING;
-            LOGV("PAUSED => RESUMING (%d) on thread %p", mName, this);
-        } else {
-            mState = TrackBase::ACTIVE;
-            LOGV("? => ACTIVE (%d) on thread %p", mName, this);
-        }
-
-        if (!isOutputTrack() && state != ACTIVE && state != RESUMING) {
-            thread->mLock.unlock();
-            status = AudioSystem::startOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
-            thread->mLock.lock();
-        }
-        if (status == NO_ERROR) {
-            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-            playbackThread->addTrack_l(this);
-        } else {
-            mState = state;
-        }
-    } else {
-        status = BAD_VALUE;
-    }
-    return status;
-}
-
-void AudioFlinger::PlaybackThread::Track::stop()
-{
-    LOGV("stop(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        Mutex::Autolock _l(thread->mLock);
-        int state = mState;
-        if (mState > STOPPED) {
-            mState = STOPPED;
-            // If the track is not active (PAUSED and buffers full), flush buffers
-            PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
-            if (playbackThread->mActiveTracks.indexOf(this) < 0) {
-                reset();
-            }
-            LOGV("(> STOPPED) => STOPPED (%d) on thread %p", mName, playbackThread);
-        }
-        if (!isOutputTrack() && (state == ACTIVE || state == RESUMING)) {
-            thread->mLock.unlock();
-            AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
-            thread->mLock.lock();
-        }
-    }
-}
-
-void AudioFlinger::PlaybackThread::Track::pause()
-{
-    LOGV("pause(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid());
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        Mutex::Autolock _l(thread->mLock);
-        if (mState == ACTIVE || mState == RESUMING) {
-            mState = PAUSING;
-            LOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get());
-            if (!isOutputTrack()) {
-                thread->mLock.unlock();
-                AudioSystem::stopOutput(thread->id(), (AudioSystem::stream_type)mStreamType);
-                thread->mLock.lock();
-            }
-        }
-    }
-}
-
-void AudioFlinger::PlaybackThread::Track::flush()
-{
-    LOGV("flush(%d)", mName);
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        Mutex::Autolock _l(thread->mLock);
-        if (mState != STOPPED && mState != PAUSED && mState != PAUSING) {
-            return;
-        }
-        // No point remaining in PAUSED state after a flush => go to
-        // STOPPED state
-        mState = STOPPED;
-
-        mCblk->lock.lock();
-        // NOTE: reset() will reset cblk->user and cblk->server with
-        // the risk that at the same time, the AudioMixer is trying to read
-        // data. In this case, getNextBuffer() would return a NULL pointer
-        // as audio buffer => the AudioMixer code MUST always test that pointer
-        // returned by getNextBuffer() is not NULL!
-        reset();
-        mCblk->lock.unlock();
-    }
-}
-
-void AudioFlinger::PlaybackThread::Track::reset()
-{
-    // Do not reset twice to avoid discarding data written just after a flush and before
-    // the audioflinger thread detects the track is stopped.
-    if (!mResetDone) {
-        TrackBase::reset();
-        // Force underrun condition to avoid false underrun callback until first data is
-        // written to buffer
-        mCblk->flowControlFlag = 1;
-        mCblk->forceReady = 0;
-        mFillingUpStatus = FS_FILLING;
-        mResetDone = true;
-    }
-}
-
-void AudioFlinger::PlaybackThread::Track::mute(bool muted)
-{
-    mMute = muted;
-}
-
-void AudioFlinger::PlaybackThread::Track::setVolume(float left, float right)
-{
-    mVolume[0] = left;
-    mVolume[1] = right;
-}
-
-// ----------------------------------------------------------------------------
-
-// RecordTrack constructor must be called with AudioFlinger::mLock held
-AudioFlinger::RecordThread::RecordTrack::RecordTrack(
-            const wp<ThreadBase>& thread,
-            const sp<Client>& client,
-            uint32_t sampleRate,
-            int format,
-            int channelCount,
-            int frameCount,
-            uint32_t flags)
-    :   TrackBase(thread, client, sampleRate, format,
-                  channelCount, frameCount, flags, 0),
-        mOverflow(false)
-{
-    if (mCblk != NULL) {
-       LOGV("RecordTrack constructor, size %d", (int)mBufferEnd - (int)mBuffer);
-       if (format == AudioSystem::PCM_16_BIT) {
-           mCblk->frameSize = channelCount * sizeof(int16_t);
-       } else if (format == AudioSystem::PCM_8_BIT) {
-           mCblk->frameSize = channelCount * sizeof(int8_t);
-       } else {
-           mCblk->frameSize = sizeof(int8_t);
-       }
-    }
-}
-
-AudioFlinger::RecordThread::RecordTrack::~RecordTrack()
-{
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        AudioSystem::releaseInput(thread->id());
-    }
-}
-
-status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
-{
-    audio_track_cblk_t* cblk = this->cblk();
-    uint32_t framesAvail;
-    uint32_t framesReq = buffer->frameCount;
-
-     // Check if last stepServer failed, try to step now
-    if (mFlags & TrackBase::STEPSERVER_FAILED) {
-        if (!step()) goto getNextBuffer_exit;
-        LOGV("stepServer recovered");
-        mFlags &= ~TrackBase::STEPSERVER_FAILED;
-    }
-
-    framesAvail = cblk->framesAvailable_l();
-
-    if (LIKELY(framesAvail)) {
-        uint32_t s = cblk->server;
-        uint32_t bufferEnd = cblk->serverBase + cblk->frameCount;
-
-        if (framesReq > framesAvail) {
-            framesReq = framesAvail;
-        }
-        if (s + framesReq > bufferEnd) {
-            framesReq = bufferEnd - s;
-        }
-
-        buffer->raw = getBuffer(s, framesReq);
-        if (buffer->raw == 0) goto getNextBuffer_exit;
-
-        buffer->frameCount = framesReq;
-        return NO_ERROR;
-    }
-
-getNextBuffer_exit:
-    buffer->raw = 0;
-    buffer->frameCount = 0;
-    return NOT_ENOUGH_DATA;
-}
-
-status_t AudioFlinger::RecordThread::RecordTrack::start()
-{
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        RecordThread *recordThread = (RecordThread *)thread.get();
-        return recordThread->start(this);
-    } else {
-        return BAD_VALUE;
-    }
-}
-
-void AudioFlinger::RecordThread::RecordTrack::stop()
-{
-    sp<ThreadBase> thread = mThread.promote();
-    if (thread != 0) {
-        RecordThread *recordThread = (RecordThread *)thread.get();
-        recordThread->stop(this);
-        TrackBase::reset();
-        // Force overerrun condition to avoid false overrun callback until first data is
-        // read from buffer
-        mCblk->flowControlFlag = 1;
-    }
-}
-
-void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
-{
-    snprintf(buffer, size, "   %05d %03u %03u %04u %01d %05u  %08x %08x\n",
-            (mClient == NULL) ? getpid() : mClient->pid(),
-            mFormat,
-            mCblk->channels,
-            mFrameCount,
-            mState,
-            mCblk->sampleRate,
-            mCblk->server,
-            mCblk->user);
-}
-
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::PlaybackThread::OutputTrack::OutputTrack(
-            const wp<ThreadBase>& thread,
-            DuplicatingThread *sourceThread,
-            uint32_t sampleRate,
-            int format,
-            int channelCount,
-            int frameCount)
-    :   Track(thread, NULL, AudioSystem::NUM_STREAM_TYPES, sampleRate, format, channelCount, frameCount, NULL),
-    mActive(false), mSourceThread(sourceThread)
-{
-
-    PlaybackThread *playbackThread = (PlaybackThread *)thread.unsafe_get();
-    if (mCblk != NULL) {
-        mCblk->out = 1;
-        mCblk->buffers = (char*)mCblk + sizeof(audio_track_cblk_t);
-        mCblk->volume[0] = mCblk->volume[1] = 0x1000;
-        mOutBuffer.frameCount = 0;
-        playbackThread->mTracks.add(this);
-        LOGV("OutputTrack constructor mCblk %p, mBuffer %p, mCblk->buffers %p, mCblk->frameCount %d, mCblk->sampleRate %d, mCblk->channels %d mBufferEnd %p",
-                mCblk, mBuffer, mCblk->buffers, mCblk->frameCount, mCblk->sampleRate, mCblk->channels, mBufferEnd);
-    } else {
-        LOGW("Error creating output track on thread %p", playbackThread);
-    }
-}
-
-AudioFlinger::PlaybackThread::OutputTrack::~OutputTrack()
-{
-    clearBufferQueue();
-}
-
-status_t AudioFlinger::PlaybackThread::OutputTrack::start()
-{
-    status_t status = Track::start();
-    if (status != NO_ERROR) {
-        return status;
-    }
-
-    mActive = true;
-    mRetryCount = 127;
-    return status;
-}
-
-void AudioFlinger::PlaybackThread::OutputTrack::stop()
-{
-    Track::stop();
-    clearBufferQueue();
-    mOutBuffer.frameCount = 0;
-    mActive = false;
-}
-
-bool AudioFlinger::PlaybackThread::OutputTrack::write(int16_t* data, uint32_t frames)
-{
-    Buffer *pInBuffer;
-    Buffer inBuffer;
-    uint32_t channels = mCblk->channels;
-    bool outputBufferFull = false;
-    inBuffer.frameCount = frames;
-    inBuffer.i16 = data;
-
-    uint32_t waitTimeLeftMs = mSourceThread->waitTimeMs();
-
-    if (!mActive && frames != 0) {
-        start();
-        sp<ThreadBase> thread = mThread.promote();
-        if (thread != 0) {
-            MixerThread *mixerThread = (MixerThread *)thread.get();
-            if (mCblk->frameCount > frames){
-                if (mBufferQueue.size() < kMaxOverFlowBuffers) {
-                    uint32_t startFrames = (mCblk->frameCount - frames);
-                    pInBuffer = new Buffer;
-                    pInBuffer->mBuffer = new int16_t[startFrames * channels];
-                    pInBuffer->frameCount = startFrames;
-                    pInBuffer->i16 = pInBuffer->mBuffer;
-                    memset(pInBuffer->raw, 0, startFrames * channels * sizeof(int16_t));
-                    mBufferQueue.add(pInBuffer);
-                } else {
-                    LOGW ("OutputTrack::write() %p no more buffers in queue", this);
-                }
-            }
-        }
-    }
-
-    while (waitTimeLeftMs) {
-        // First write pending buffers, then new data
-        if (mBufferQueue.size()) {
-            pInBuffer = mBufferQueue.itemAt(0);
-        } else {
-            pInBuffer = &inBuffer;
-        }
-
-        if (pInBuffer->frameCount == 0) {
-            break;
-        }
-
-        if (mOutBuffer.frameCount == 0) {
-            mOutBuffer.frameCount = pInBuffer->frameCount;
-            nsecs_t startTime = systemTime();
-            if (obtainBuffer(&mOutBuffer, waitTimeLeftMs) == (status_t)AudioTrack::NO_MORE_BUFFERS) {
-                LOGV ("OutputTrack::write() %p thread %p no more output buffers", this, mThread.unsafe_get());
-                outputBufferFull = true;
-                break;
-            }
-            uint32_t waitTimeMs = (uint32_t)ns2ms(systemTime() - startTime);
-            if (waitTimeLeftMs >= waitTimeMs) {
-                waitTimeLeftMs -= waitTimeMs;
-            } else {
-                waitTimeLeftMs = 0;
-            }
-        }
-
-        uint32_t outFrames = pInBuffer->frameCount > mOutBuffer.frameCount ? mOutBuffer.frameCount : pInBuffer->frameCount;
-        memcpy(mOutBuffer.raw, pInBuffer->raw, outFrames * channels * sizeof(int16_t));
-        mCblk->stepUser(outFrames);
-        pInBuffer->frameCount -= outFrames;
-        pInBuffer->i16 += outFrames * channels;
-        mOutBuffer.frameCount -= outFrames;
-        mOutBuffer.i16 += outFrames * channels;
-
-        if (pInBuffer->frameCount == 0) {
-            if (mBufferQueue.size()) {
-                mBufferQueue.removeAt(0);
-                delete [] pInBuffer->mBuffer;
-                delete pInBuffer;
-                LOGV("OutputTrack::write() %p thread %p released overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
-            } else {
-                break;
-            }
-        }
-    }
-
-    // If we could not write all frames, allocate a buffer and queue it for next time.
-    if (inBuffer.frameCount) {
-        sp<ThreadBase> thread = mThread.promote();
-        if (thread != 0 && !thread->standby()) {
-            if (mBufferQueue.size() < kMaxOverFlowBuffers) {
-                pInBuffer = new Buffer;
-                pInBuffer->mBuffer = new int16_t[inBuffer.frameCount * channels];
-                pInBuffer->frameCount = inBuffer.frameCount;
-                pInBuffer->i16 = pInBuffer->mBuffer;
-                memcpy(pInBuffer->raw, inBuffer.raw, inBuffer.frameCount * channels * sizeof(int16_t));
-                mBufferQueue.add(pInBuffer);
-                LOGV("OutputTrack::write() %p thread %p adding overflow buffer %d", this, mThread.unsafe_get(), mBufferQueue.size());
-            } else {
-                LOGW("OutputTrack::write() %p thread %p no more overflow buffers", mThread.unsafe_get(), this);
-            }
-        }
-    }
-
-    // Calling write() with a 0 length buffer, means that no more data will be written:
-    // If no more buffers are pending, fill output track buffer to make sure it is started
-    // by output mixer.
-    if (frames == 0 && mBufferQueue.size() == 0) {
-        if (mCblk->user < mCblk->frameCount) {
-            frames = mCblk->frameCount - mCblk->user;
-            pInBuffer = new Buffer;
-            pInBuffer->mBuffer = new int16_t[frames * channels];
-            pInBuffer->frameCount = frames;
-            pInBuffer->i16 = pInBuffer->mBuffer;
-            memset(pInBuffer->raw, 0, frames * channels * sizeof(int16_t));
-            mBufferQueue.add(pInBuffer);
-        } else if (mActive) {
-            stop();
-        }
-    }
-
-    return outputBufferFull;
-}
-
-status_t AudioFlinger::PlaybackThread::OutputTrack::obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs)
-{
-    int active;
-    status_t result;
-    audio_track_cblk_t* cblk = mCblk;
-    uint32_t framesReq = buffer->frameCount;
-
-//    LOGV("OutputTrack::obtainBuffer user %d, server %d", cblk->user, cblk->server);
-    buffer->frameCount  = 0;
-
-    uint32_t framesAvail = cblk->framesAvailable();
-
-
-    if (framesAvail == 0) {
-        Mutex::Autolock _l(cblk->lock);
-        goto start_loop_here;
-        while (framesAvail == 0) {
-            active = mActive;
-            if (UNLIKELY(!active)) {
-                LOGV("Not active and NO_MORE_BUFFERS");
-                return AudioTrack::NO_MORE_BUFFERS;
-            }
-            result = cblk->cv.waitRelative(cblk->lock, milliseconds(waitTimeMs));
-            if (result != NO_ERROR) {
-                return AudioTrack::NO_MORE_BUFFERS;
-            }
-            // read the server count again
-        start_loop_here:
-            framesAvail = cblk->framesAvailable_l();
-        }
-    }
-
-//    if (framesAvail < framesReq) {
-//        return AudioTrack::NO_MORE_BUFFERS;
-//    }
-
-    if (framesReq > framesAvail) {
-        framesReq = framesAvail;
-    }
-
-    uint32_t u = cblk->user;
-    uint32_t bufferEnd = cblk->userBase + cblk->frameCount;
-
-    if (u + framesReq > bufferEnd) {
-        framesReq = bufferEnd - u;
-    }
-
-    buffer->frameCount  = framesReq;
-    buffer->raw         = (void *)cblk->buffer(u);
-    return NO_ERROR;
-}
-
-
-void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
-{
-    size_t size = mBufferQueue.size();
-    Buffer *pBuffer;
-
-    for (size_t i = 0; i < size; i++) {
-        pBuffer = mBufferQueue.itemAt(i);
-        delete [] pBuffer->mBuffer;
-        delete pBuffer;
-    }
-    mBufferQueue.clear();
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
-    :   RefBase(),
-        mAudioFlinger(audioFlinger),
-        mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
-        mPid(pid)
-{
-    // 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
-}
-
-// Client destructor must be called with AudioFlinger::mLock held
-AudioFlinger::Client::~Client()
-{
-    mAudioFlinger->removeClient_l(mPid);
-}
-
-const sp<MemoryDealer>& AudioFlinger::Client::heap() const
-{
-    return mMemoryDealer;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::TrackHandle::TrackHandle(const sp<AudioFlinger::PlaybackThread::Track>& track)
-    : BnAudioTrack(),
-      mTrack(track)
-{
-}
-
-AudioFlinger::TrackHandle::~TrackHandle() {
-    // just stop the track on deletion, associated resources
-    // will be freed from the main thread once all pending buffers have
-    // been played. Unless it's not in the active track list, in which
-    // case we free everything now...
-    mTrack->destroy();
-}
-
-status_t AudioFlinger::TrackHandle::start() {
-    return mTrack->start();
-}
-
-void AudioFlinger::TrackHandle::stop() {
-    mTrack->stop();
-}
-
-void AudioFlinger::TrackHandle::flush() {
-    mTrack->flush();
-}
-
-void AudioFlinger::TrackHandle::mute(bool e) {
-    mTrack->mute(e);
-}
-
-void AudioFlinger::TrackHandle::pause() {
-    mTrack->pause();
-}
-
-void AudioFlinger::TrackHandle::setVolume(float left, float right) {
-    mTrack->setVolume(left, right);
-}
-
-sp<IMemory> AudioFlinger::TrackHandle::getCblk() const {
-    return mTrack->getCblk();
-}
-
-status_t AudioFlinger::TrackHandle::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnAudioTrack::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-
-sp<IAudioRecord> AudioFlinger::openRecord(
-        pid_t pid,
-        int input,
-        uint32_t sampleRate,
-        int format,
-        int channelCount,
-        int frameCount,
-        uint32_t flags,
-        status_t *status)
-{
-    sp<RecordThread::RecordTrack> recordTrack;
-    sp<RecordHandle> recordHandle;
-    sp<Client> client;
-    wp<Client> wclient;
-    status_t lStatus;
-    RecordThread *thread;
-    size_t inFrameCount;
-
-    // check calling permissions
-    if (!recordingAllowed()) {
-        lStatus = PERMISSION_DENIED;
-        goto Exit;
-    }
-
-    // add client to list
-    { // scope for mLock
-        Mutex::Autolock _l(mLock);
-        thread = checkRecordThread_l(input);
-        if (thread == NULL) {
-            lStatus = BAD_VALUE;
-            goto Exit;
-        }
-
-        wclient = mClients.valueFor(pid);
-        if (wclient != NULL) {
-            client = wclient.promote();
-        } else {
-            client = new Client(this, pid);
-            mClients.add(pid, client);
-        }
-
-        // create new record track. The record track uses one track in mHardwareMixerThread by convention.
-        recordTrack = new RecordThread::RecordTrack(thread, client, sampleRate,
-                                                   format, channelCount, frameCount, flags);
-    }
-    if (recordTrack->getCblk() == NULL) {
-        // remove local strong reference to Client before deleting the RecordTrack so that the Client
-        // destructor is called by the TrackBase destructor with mLock held
-        client.clear();
-        recordTrack.clear();
-        lStatus = NO_MEMORY;
-        goto Exit;
-    }
-
-    // return to handle to client
-    recordHandle = new RecordHandle(recordTrack);
-    lStatus = NO_ERROR;
-
-Exit:
-    if (status) {
-        *status = lStatus;
-    }
-    return recordHandle;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::RecordHandle::RecordHandle(const sp<AudioFlinger::RecordThread::RecordTrack>& recordTrack)
-    : BnAudioRecord(),
-    mRecordTrack(recordTrack)
-{
-}
-
-AudioFlinger::RecordHandle::~RecordHandle() {
-    stop();
-}
-
-status_t AudioFlinger::RecordHandle::start() {
-    LOGV("RecordHandle::start()");
-    return mRecordTrack->start();
-}
-
-void AudioFlinger::RecordHandle::stop() {
-    LOGV("RecordHandle::stop()");
-    mRecordTrack->stop();
-}
-
-sp<IMemory> AudioFlinger::RecordHandle::getCblk() const {
-    return mRecordTrack->getCblk();
-}
-
-status_t AudioFlinger::RecordHandle::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnAudioRecord::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-
-AudioFlinger::RecordThread::RecordThread(const sp<AudioFlinger>& audioFlinger, AudioStreamIn *input, uint32_t sampleRate, uint32_t channels, int id) :
-    ThreadBase(audioFlinger, id),
-    mInput(input), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
-{
-    mReqChannelCount = AudioSystem::popCount(channels);
-    mReqSampleRate = sampleRate;
-    readInputParameters();
-    sendConfigEvent(AudioSystem::INPUT_OPENED);
-}
-
-
-AudioFlinger::RecordThread::~RecordThread()
-{
-    delete[] mRsmpInBuffer;
-    if (mResampler != 0) {
-        delete mResampler;
-        delete[] mRsmpOutBuffer;
-    }
-}
-
-void AudioFlinger::RecordThread::onFirstRef()
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "Record Thread %p", this);
-
-    run(buffer, PRIORITY_URGENT_AUDIO);
-}
-
-bool AudioFlinger::RecordThread::threadLoop()
-{
-    AudioBufferProvider::Buffer buffer;
-    sp<RecordTrack> activeTrack;
-
-    // start recording
-    while (!exitPending()) {
-
-        processConfigEvents();
-
-        { // scope for mLock
-            Mutex::Autolock _l(mLock);
-            checkForNewParameters_l();
-            if (mActiveTrack == 0 && mConfigEvents.isEmpty()) {
-                if (!mStandby) {
-                    mInput->standby();
-                    mStandby = true;
-                }
-
-                if (exitPending()) break;
-
-                LOGV("RecordThread: loop stopping");
-                // go to sleep
-                mWaitWorkCV.wait(mLock);
-                LOGV("RecordThread: loop starting");
-                continue;
-            }
-            if (mActiveTrack != 0) {
-                if (mActiveTrack->mState == TrackBase::PAUSING) {
-                    if (!mStandby) {
-                        mInput->standby();
-                        mStandby = true;
-                    }
-                    mActiveTrack.clear();
-                    mStartStopCond.broadcast();
-                } else if (mActiveTrack->mState == TrackBase::RESUMING) {
-                    if (mReqChannelCount != mActiveTrack->channelCount()) {
-                        mActiveTrack.clear();
-                        mStartStopCond.broadcast();
-                    } else if (mBytesRead != 0) {
-                        // record start succeeds only if first read from audio input
-                        // succeeds
-                        if (mBytesRead > 0) {
-                            mActiveTrack->mState = TrackBase::ACTIVE;
-                        } else {
-                            mActiveTrack.clear();
-                        }
-                        mStartStopCond.broadcast();
-                    }
-                    mStandby = false;
-                }
-            }
-        }
-
-        if (mActiveTrack != 0) {
-            if (mActiveTrack->mState != TrackBase::ACTIVE &&
-                mActiveTrack->mState != TrackBase::RESUMING) {
-                usleep(5000);
-                continue;
-            }
-            buffer.frameCount = mFrameCount;
-            if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
-                size_t framesOut = buffer.frameCount;
-                if (mResampler == 0) {
-                    // no resampling
-                    while (framesOut) {
-                        size_t framesIn = mFrameCount - mRsmpInIndex;
-                        if (framesIn) {
-                            int8_t *src = (int8_t *)mRsmpInBuffer + mRsmpInIndex * mFrameSize;
-                            int8_t *dst = buffer.i8 + (buffer.frameCount - framesOut) * mActiveTrack->mCblk->frameSize;
-                            if (framesIn > framesOut)
-                                framesIn = framesOut;
-                            mRsmpInIndex += framesIn;
-                            framesOut -= framesIn;
-                            if (mChannelCount == mReqChannelCount ||
-                                mFormat != AudioSystem::PCM_16_BIT) {
-                                memcpy(dst, src, framesIn * mFrameSize);
-                            } else {
-                                int16_t *src16 = (int16_t *)src;
-                                int16_t *dst16 = (int16_t *)dst;
-                                if (mChannelCount == 1) {
-                                    while (framesIn--) {
-                                        *dst16++ = *src16;
-                                        *dst16++ = *src16++;
-                                    }
-                                } else {
-                                    while (framesIn--) {
-                                        *dst16++ = (int16_t)(((int32_t)*src16 + (int32_t)*(src16 + 1)) >> 1);
-                                        src16 += 2;
-                                    }
-                                }
-                            }
-                        }
-                        if (framesOut && mFrameCount == mRsmpInIndex) {
-                            if (framesOut == mFrameCount &&
-                                (mChannelCount == mReqChannelCount || mFormat != AudioSystem::PCM_16_BIT)) {
-                                mBytesRead = mInput->read(buffer.raw, mInputBytes);
-                                framesOut = 0;
-                            } else {
-                                mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
-                                mRsmpInIndex = 0;
-                            }
-                            if (mBytesRead < 0) {
-                                LOGE("Error reading audio input");
-                                if (mActiveTrack->mState == TrackBase::ACTIVE) {
-                                    // Force input into standby so that it tries to
-                                    // recover at next read attempt
-                                    mInput->standby();
-                                    usleep(5000);
-                                }
-                                mRsmpInIndex = mFrameCount;
-                                framesOut = 0;
-                                buffer.frameCount = 0;
-                            }
-                        }
-                    }
-                } else {
-                    // resampling
-
-                    memset(mRsmpOutBuffer, 0, framesOut * 2 * sizeof(int32_t));
-                    // alter output frame count as if we were expecting stereo samples
-                    if (mChannelCount == 1 && mReqChannelCount == 1) {
-                        framesOut >>= 1;
-                    }
-                    mResampler->resample(mRsmpOutBuffer, framesOut, this);
-                    // ditherAndClamp() works as long as all buffers returned by mActiveTrack->getNextBuffer()
-                    // are 32 bit aligned which should be always true.
-                    if (mChannelCount == 2 && mReqChannelCount == 1) {
-                        AudioMixer::ditherAndClamp(mRsmpOutBuffer, mRsmpOutBuffer, framesOut);
-                        // the resampler always outputs stereo samples: do post stereo to mono conversion
-                        int16_t *src = (int16_t *)mRsmpOutBuffer;
-                        int16_t *dst = buffer.i16;
-                        while (framesOut--) {
-                            *dst++ = (int16_t)(((int32_t)*src + (int32_t)*(src + 1)) >> 1);
-                            src += 2;
-                        }
-                    } else {
-                        AudioMixer::ditherAndClamp((int32_t *)buffer.raw, mRsmpOutBuffer, framesOut);
-                    }
-
-                }
-                mActiveTrack->releaseBuffer(&buffer);
-                mActiveTrack->overflow();
-            }
-            // client isn't retrieving buffers fast enough
-            else {
-                if (!mActiveTrack->setOverflow())
-                    LOGW("RecordThread: buffer overflow");
-                // Release the processor for a while before asking for a new buffer.
-                // This will give the application more chance to read from the buffer and
-                // clear the overflow.
-                usleep(5000);
-            }
-        }
-    }
-
-    if (!mStandby) {
-        mInput->standby();
-    }
-    mActiveTrack.clear();
-
-    mStartStopCond.broadcast();
-
-    LOGV("RecordThread %p exiting", this);
-    return false;
-}
-
-status_t AudioFlinger::RecordThread::start(RecordThread::RecordTrack* recordTrack)
-{
-    LOGV("RecordThread::start");
-    sp <ThreadBase> strongMe = this;
-    status_t status = NO_ERROR;
-    {
-        AutoMutex lock(&mLock);
-        if (mActiveTrack != 0) {
-            if (recordTrack != mActiveTrack.get()) {
-                status = -EBUSY;
-            } else if (mActiveTrack->mState == TrackBase::PAUSING) {
-                mActiveTrack->mState = TrackBase::ACTIVE;
-            }
-            return status;
-        }
-
-        recordTrack->mState = TrackBase::IDLE;
-        mActiveTrack = recordTrack;
-        mLock.unlock();
-        status_t status = AudioSystem::startInput(mId);
-        mLock.lock();
-        if (status != NO_ERROR) {
-            mActiveTrack.clear();
-            return status;
-        }
-        mActiveTrack->mState = TrackBase::RESUMING;
-        mRsmpInIndex = mFrameCount;
-        mBytesRead = 0;
-        // signal thread to start
-        LOGV("Signal record thread");
-        mWaitWorkCV.signal();
-        // do not wait for mStartStopCond if exiting
-        if (mExiting) {
-            mActiveTrack.clear();
-            status = INVALID_OPERATION;
-            goto startError;
-        }
-        mStartStopCond.wait(mLock);
-        if (mActiveTrack == 0) {
-            LOGV("Record failed to start");
-            status = BAD_VALUE;
-            goto startError;
-        }
-        LOGV("Record started OK");
-        return status;
-    }
-startError:
-    AudioSystem::stopInput(mId);
-    return status;
-}
-
-void AudioFlinger::RecordThread::stop(RecordThread::RecordTrack* recordTrack) {
-    LOGV("RecordThread::stop");
-    sp <ThreadBase> strongMe = this;
-    {
-        AutoMutex lock(&mLock);
-        if (mActiveTrack != 0 && recordTrack == mActiveTrack.get()) {
-            mActiveTrack->mState = TrackBase::PAUSING;
-            // do not wait for mStartStopCond if exiting
-            if (mExiting) {
-                return;
-            }
-            mStartStopCond.wait(mLock);
-            // if we have been restarted, recordTrack == mActiveTrack.get() here
-            if (mActiveTrack == 0 || recordTrack != mActiveTrack.get()) {
-                mLock.unlock();
-                AudioSystem::stopInput(mId);
-                mLock.lock();
-                LOGV("Record stopped OK");
-            }
-        }
-    }
-}
-
-status_t AudioFlinger::RecordThread::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    pid_t pid = 0;
-
-    snprintf(buffer, SIZE, "\nInput thread %p internals\n", this);
-    result.append(buffer);
-
-    if (mActiveTrack != 0) {
-        result.append("Active Track:\n");
-        result.append("   Clien Fmt Chn Buf  S SRate  Serv     User\n");
-        mActiveTrack->dump(buffer, SIZE);
-        result.append(buffer);
-
-        snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
-        result.append(buffer);
-        snprintf(buffer, SIZE, "In size: %d\n", mInputBytes);
-        result.append(buffer);
-        snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != 0));
-        result.append(buffer);
-        snprintf(buffer, SIZE, "Out channel count: %d\n", mReqChannelCount);
-        result.append(buffer);
-        snprintf(buffer, SIZE, "Out sample rate: %d\n", mReqSampleRate);
-        result.append(buffer);
-
-
-    } else {
-        result.append("No record client\n");
-    }
-    write(fd, result.string(), result.size());
-
-    dumpBase(fd, args);
-
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer)
-{
-    size_t framesReq = buffer->frameCount;
-    size_t framesReady = mFrameCount - mRsmpInIndex;
-    int channelCount;
-
-    if (framesReady == 0) {
-        mBytesRead = mInput->read(mRsmpInBuffer, mInputBytes);
-        if (mBytesRead < 0) {
-            LOGE("RecordThread::getNextBuffer() Error reading audio input");
-            if (mActiveTrack->mState == TrackBase::ACTIVE) {
-                // Force input into standby so that it tries to
-                // recover at next read attempt
-                mInput->standby();
-                usleep(5000);
-            }
-            buffer->raw = 0;
-            buffer->frameCount = 0;
-            return NOT_ENOUGH_DATA;
-        }
-        mRsmpInIndex = 0;
-        framesReady = mFrameCount;
-    }
-
-    if (framesReq > framesReady) {
-        framesReq = framesReady;
-    }
-
-    if (mChannelCount == 1 && mReqChannelCount == 2) {
-        channelCount = 1;
-    } else {
-        channelCount = 2;
-    }
-    buffer->raw = mRsmpInBuffer + mRsmpInIndex * channelCount;
-    buffer->frameCount = framesReq;
-    return NO_ERROR;
-}
-
-void AudioFlinger::RecordThread::releaseBuffer(AudioBufferProvider::Buffer* buffer)
-{
-    mRsmpInIndex += buffer->frameCount;
-    buffer->frameCount = 0;
-}
-
-bool AudioFlinger::RecordThread::checkForNewParameters_l()
-{
-    bool reconfig = false;
-
-    while (!mNewParameters.isEmpty()) {
-        status_t status = NO_ERROR;
-        String8 keyValuePair = mNewParameters[0];
-        AudioParameter param = AudioParameter(keyValuePair);
-        int value;
-        int reqFormat = mFormat;
-        int reqSamplingRate = mReqSampleRate;
-        int reqChannelCount = mReqChannelCount;
-
-        if (param.getInt(String8(AudioParameter::keySamplingRate), value) == NO_ERROR) {
-            reqSamplingRate = value;
-            reconfig = true;
-        }
-        if (param.getInt(String8(AudioParameter::keyFormat), value) == NO_ERROR) {
-            reqFormat = value;
-            reconfig = true;
-        }
-        if (param.getInt(String8(AudioParameter::keyChannels), value) == NO_ERROR) {
-            reqChannelCount = AudioSystem::popCount(value);
-            reconfig = true;
-        }
-        if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
-            // do not accept frame count changes if tracks are open as the track buffer
-            // size depends on frame count and correct behavior would not be garantied
-            // if frame count is changed after track creation
-            if (mActiveTrack != 0) {
-                status = INVALID_OPERATION;
-            } else {
-                reconfig = true;
-            }
-        }
-        if (status == NO_ERROR) {
-            status = mInput->setParameters(keyValuePair);
-            if (status == INVALID_OPERATION) {
-               mInput->standby();
-               status = mInput->setParameters(keyValuePair);
-            }
-            if (reconfig) {
-                if (status == BAD_VALUE &&
-                    reqFormat == mInput->format() && reqFormat == AudioSystem::PCM_16_BIT &&
-                    ((int)mInput->sampleRate() <= 2 * reqSamplingRate) &&
-                    (AudioSystem::popCount(mInput->channels()) < 3) && (reqChannelCount < 3)) {
-                    status = NO_ERROR;
-                }
-                if (status == NO_ERROR) {
-                    readInputParameters();
-                    sendConfigEvent_l(AudioSystem::INPUT_CONFIG_CHANGED);
-                }
-            }
-        }
-
-        mNewParameters.removeAt(0);
-
-        mParamStatus = status;
-        mParamCond.signal();
-        mWaitWorkCV.wait(mLock);
-    }
-    return reconfig;
-}
-
-String8 AudioFlinger::RecordThread::getParameters(const String8& keys)
-{
-    return mInput->getParameters(keys);
-}
-
-void AudioFlinger::RecordThread::audioConfigChanged(int event, int param) {
-    AudioSystem::OutputDescriptor desc;
-    void *param2 = 0;
-
-    switch (event) {
-    case AudioSystem::INPUT_OPENED:
-    case AudioSystem::INPUT_CONFIG_CHANGED:
-        desc.channels = mChannelCount;
-        desc.samplingRate = mSampleRate;
-        desc.format = mFormat;
-        desc.frameCount = mFrameCount;
-        desc.latency = 0;
-        param2 = &desc;
-        break;
-
-    case AudioSystem::INPUT_CLOSED:
-    default:
-        break;
-    }
-    Mutex::Autolock _l(mAudioFlinger->mLock);
-    mAudioFlinger->audioConfigChanged_l(event, mId, param2);
-}
-
-void AudioFlinger::RecordThread::readInputParameters()
-{
-    if (mRsmpInBuffer) delete mRsmpInBuffer;
-    if (mRsmpOutBuffer) delete mRsmpOutBuffer;
-    if (mResampler) delete mResampler;
-    mResampler = 0;
-
-    mSampleRate = mInput->sampleRate();
-    mChannelCount = AudioSystem::popCount(mInput->channels());
-    mFormat = mInput->format();
-    mFrameSize = mInput->frameSize();
-    mInputBytes = mInput->bufferSize();
-    mFrameCount = mInputBytes / mFrameSize;
-    mRsmpInBuffer = new int16_t[mFrameCount * mChannelCount];
-
-    if (mSampleRate != mReqSampleRate && mChannelCount < 3 && mReqChannelCount < 3)
-    {
-        int channelCount;
-         // optmization: if mono to mono, use the resampler in stereo to stereo mode to avoid
-         // stereo to mono post process as the resampler always outputs stereo.
-        if (mChannelCount == 1 && mReqChannelCount == 2) {
-            channelCount = 1;
-        } else {
-            channelCount = 2;
-        }
-        mResampler = AudioResampler::create(16, channelCount, mReqSampleRate);
-        mResampler->setSampleRate(mSampleRate);
-        mResampler->setVolume(AudioMixer::UNITY_GAIN, AudioMixer::UNITY_GAIN);
-        mRsmpOutBuffer = new int32_t[mFrameCount * 2];
-
-        // optmization: if mono to mono, alter input frame count as if we were inputing stereo samples
-        if (mChannelCount == 1 && mReqChannelCount == 1) {
-            mFrameCount >>= 1;
-        }
-
-    }
-    mRsmpInIndex = mFrameCount;
-}
-
-unsigned int AudioFlinger::RecordThread::getInputFramesLost()
-{
-    return mInput->getInputFramesLost();
-}
-
-// ----------------------------------------------------------------------------
-
-int AudioFlinger::openOutput(uint32_t *pDevices,
-                                uint32_t *pSamplingRate,
-                                uint32_t *pFormat,
-                                uint32_t *pChannels,
-                                uint32_t *pLatencyMs,
-                                uint32_t flags)
-{
-    status_t status;
-    PlaybackThread *thread = NULL;
-    mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
-    uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
-    uint32_t format = pFormat ? *pFormat : 0;
-    uint32_t channels = pChannels ? *pChannels : 0;
-    uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
-
-    LOGV("openOutput(), Device %x, SamplingRate %d, Format %d, Channels %x, flags %x",
-            pDevices ? *pDevices : 0,
-            samplingRate,
-            format,
-            channels,
-            flags);
-
-    if (pDevices == NULL || *pDevices == 0) {
-        return 0;
-    }
-    Mutex::Autolock _l(mLock);
-
-    AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices,
-                                                             (int *)&format,
-                                                             &channels,
-                                                             &samplingRate,
-                                                             &status);
-    LOGV("openOutput() openOutputStream returned output %p, SamplingRate %d, Format %d, Channels %x, status %d",
-            output,
-            samplingRate,
-            format,
-            channels,
-            status);
-
-    mHardwareStatus = AUDIO_HW_IDLE;
-    if (output != 0) {
-        if ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
-            (format != AudioSystem::PCM_16_BIT) ||
-            (channels != AudioSystem::CHANNEL_OUT_STEREO)) {
-            thread = new DirectOutputThread(this, output, ++mNextThreadId);
-            LOGV("openOutput() created direct output: ID %d thread %p", mNextThreadId, thread);
-        } else {
-            thread = new MixerThread(this, output, ++mNextThreadId);
-            LOGV("openOutput() created mixer output: ID %d thread %p", mNextThreadId, thread);
-
-#ifdef LVMX
-            unsigned bitsPerSample =
-                (format == AudioSystem::PCM_16_BIT) ? 16 :
-                    ((format == AudioSystem::PCM_8_BIT) ? 8 : 0);
-            unsigned channelCount = (channels == AudioSystem::CHANNEL_OUT_STEREO) ? 2 : 1;
-            int audioOutputType = LifeVibes::threadIdToAudioOutputType(thread->id());
-
-            LifeVibes::init_aot(audioOutputType, samplingRate, bitsPerSample, channelCount);
-            LifeVibes::setDevice(audioOutputType, *pDevices);
-#endif
-
-        }
-        mPlaybackThreads.add(mNextThreadId, thread);
-
-        if (pSamplingRate) *pSamplingRate = samplingRate;
-        if (pFormat) *pFormat = format;
-        if (pChannels) *pChannels = channels;
-        if (pLatencyMs) *pLatencyMs = thread->latency();
-
-        return mNextThreadId;
-    }
-
-    return 0;
-}
-
-int AudioFlinger::openDuplicateOutput(int output1, int output2)
-{
-    Mutex::Autolock _l(mLock);
-    MixerThread *thread1 = checkMixerThread_l(output1);
-    MixerThread *thread2 = checkMixerThread_l(output2);
-
-    if (thread1 == NULL || thread2 == NULL) {
-        LOGW("openDuplicateOutput() wrong output mixer type for output %d or %d", output1, output2);
-        return 0;
-    }
-
-
-    DuplicatingThread *thread = new DuplicatingThread(this, thread1, ++mNextThreadId);
-    thread->addOutputTrack(thread2);
-    mPlaybackThreads.add(mNextThreadId, thread);
-    return mNextThreadId;
-}
-
-status_t AudioFlinger::closeOutput(int output)
-{
-    // keep strong reference on the playback thread so that
-    // it is not destroyed while exit() is executed
-    sp <PlaybackThread> thread;
-    {
-        Mutex::Autolock _l(mLock);
-        thread = checkPlaybackThread_l(output);
-        if (thread == NULL) {
-            return BAD_VALUE;
-        }
-
-        LOGV("closeOutput() %d", output);
-
-        if (thread->type() == PlaybackThread::MIXER) {
-            for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-                if (mPlaybackThreads.valueAt(i)->type() == PlaybackThread::DUPLICATING) {
-                    DuplicatingThread *dupThread = (DuplicatingThread *)mPlaybackThreads.valueAt(i).get();
-                    dupThread->removeOutputTrack((MixerThread *)thread.get());
-                }
-            }
-        }
-        void *param2 = 0;
-        audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2);
-        mPlaybackThreads.removeItem(output);
-    }
-    thread->exit();
-
-    if (thread->type() != PlaybackThread::DUPLICATING) {
-        mAudioHardware->closeOutputStream(thread->getOutput());
-    }
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::suspendOutput(int output)
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-
-    if (thread == NULL) {
-        return BAD_VALUE;
-    }
-
-    LOGV("suspendOutput() %d", output);
-    thread->suspend();
-
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::restoreOutput(int output)
-{
-    Mutex::Autolock _l(mLock);
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-
-    if (thread == NULL) {
-        return BAD_VALUE;
-    }
-
-    LOGV("restoreOutput() %d", output);
-
-    thread->restore();
-
-    return NO_ERROR;
-}
-
-int AudioFlinger::openInput(uint32_t *pDevices,
-                                uint32_t *pSamplingRate,
-                                uint32_t *pFormat,
-                                uint32_t *pChannels,
-                                uint32_t acoustics)
-{
-    status_t status;
-    RecordThread *thread = NULL;
-    uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
-    uint32_t format = pFormat ? *pFormat : 0;
-    uint32_t channels = pChannels ? *pChannels : 0;
-    uint32_t reqSamplingRate = samplingRate;
-    uint32_t reqFormat = format;
-    uint32_t reqChannels = channels;
-
-    if (pDevices == NULL || *pDevices == 0) {
-        return 0;
-    }
-    Mutex::Autolock _l(mLock);
-
-    AudioStreamIn *input = mAudioHardware->openInputStream(*pDevices,
-                                                             (int *)&format,
-                                                             &channels,
-                                                             &samplingRate,
-                                                             &status,
-                                                             (AudioSystem::audio_in_acoustics)acoustics);
-    LOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %d, Channels %x, acoustics %x, status %d",
-            input,
-            samplingRate,
-            format,
-            channels,
-            acoustics,
-            status);
-
-    // If the input could not be opened with the requested parameters and we can handle the conversion internally,
-    // try to open again with the proposed parameters. The AudioFlinger can resample the input and do mono to stereo
-    // or stereo to mono conversions on 16 bit PCM inputs.
-    if (input == 0 && status == BAD_VALUE &&
-        reqFormat == format && format == AudioSystem::PCM_16_BIT &&
-        (samplingRate <= 2 * reqSamplingRate) &&
-        (AudioSystem::popCount(channels) < 3) && (AudioSystem::popCount(reqChannels) < 3)) {
-        LOGV("openInput() reopening with proposed sampling rate and channels");
-        input = mAudioHardware->openInputStream(*pDevices,
-                                                 (int *)&format,
-                                                 &channels,
-                                                 &samplingRate,
-                                                 &status,
-                                                 (AudioSystem::audio_in_acoustics)acoustics);
-    }
-
-    if (input != 0) {
-         // Start record thread
-        thread = new RecordThread(this, input, reqSamplingRate, reqChannels, ++mNextThreadId);
-        mRecordThreads.add(mNextThreadId, thread);
-        LOGV("openInput() created record thread: ID %d thread %p", mNextThreadId, thread);
-        if (pSamplingRate) *pSamplingRate = reqSamplingRate;
-        if (pFormat) *pFormat = format;
-        if (pChannels) *pChannels = reqChannels;
-
-        input->standby();
-
-        return mNextThreadId;
-    }
-
-    return 0;
-}
-
-status_t AudioFlinger::closeInput(int input)
-{
-    // keep strong reference on the record thread so that
-    // it is not destroyed while exit() is executed
-    sp <RecordThread> thread;
-    {
-        Mutex::Autolock _l(mLock);
-        thread = checkRecordThread_l(input);
-        if (thread == NULL) {
-            return BAD_VALUE;
-        }
-
-        LOGV("closeInput() %d", input);
-        void *param2 = 0;
-        audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2);
-        mRecordThreads.removeItem(input);
-    }
-    thread->exit();
-
-    mAudioHardware->closeInputStream(thread->getInput());
-
-    return NO_ERROR;
-}
-
-status_t AudioFlinger::setStreamOutput(uint32_t stream, int output)
-{
-    Mutex::Autolock _l(mLock);
-    MixerThread *dstThread = checkMixerThread_l(output);
-    if (dstThread == NULL) {
-        LOGW("setStreamOutput() bad output id %d", output);
-        return BAD_VALUE;
-    }
-
-    LOGV("setStreamOutput() stream %d to output %d", stream, output);
-
-    for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
-        PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
-        if (thread != dstThread &&
-            thread->type() != PlaybackThread::DIRECT) {
-            MixerThread *srcThread = (MixerThread *)thread;
-            SortedVector < sp<MixerThread::Track> > tracks;
-            SortedVector < wp<MixerThread::Track> > activeTracks;
-            srcThread->getTracks(tracks, activeTracks, stream);
-            if (tracks.size()) {
-                dstThread->putTracks(tracks, activeTracks);
-            }
-        }
-    }
-
-    dstThread->sendConfigEvent(AudioSystem::STREAM_CONFIG_CHANGED, stream);
-
-    return NO_ERROR;
-}
-
-// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(int output) const
-{
-    PlaybackThread *thread = NULL;
-    if (mPlaybackThreads.indexOfKey(output) >= 0) {
-        thread = (PlaybackThread *)mPlaybackThreads.valueFor(output).get();
-    }
-    return thread;
-}
-
-// checkMixerThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(int output) const
-{
-    PlaybackThread *thread = checkPlaybackThread_l(output);
-    if (thread != NULL) {
-        if (thread->type() == PlaybackThread::DIRECT) {
-            thread = NULL;
-        }
-    }
-    return (MixerThread *)thread;
-}
-
-// checkRecordThread_l() must be called with AudioFlinger::mLock held
-AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(int input) const
-{
-    RecordThread *thread = NULL;
-    if (mRecordThreads.indexOfKey(input) >= 0) {
-        thread = (RecordThread *)mRecordThreads.valueFor(input).get();
-    }
-    return thread;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioFlinger::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnAudioFlinger::onTransact(code, data, reply, flags);
-}
-
-// ----------------------------------------------------------------------------
-
-void AudioFlinger::instantiate() {
-    defaultServiceManager()->addService(
-            String16("media.audio_flinger"), new AudioFlinger());
-}
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
deleted file mode 100644
index 739ec33..0000000
--- a/libs/audioflinger/AudioFlinger.h
+++ /dev/null
@@ -1,807 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioFlinger.h
-**
-** 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.
-*/
-
-#ifndef ANDROID_AUDIO_FLINGER_H
-#define ANDROID_AUDIO_FLINGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <limits.h>
-
-#include <media/IAudioFlinger.h>
-#include <media/IAudioFlingerClient.h>
-#include <media/IAudioTrack.h>
-#include <media/IAudioRecord.h>
-#include <media/AudioTrack.h>
-
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/threads.h>
-#include <binder/MemoryDealer.h>
-#include <utils/SortedVector.h>
-#include <utils/Vector.h>
-
-#include <hardware_legacy/AudioHardwareInterface.h>
-
-#include "AudioBufferProvider.h"
-
-namespace android {
-
-class audio_track_cblk_t;
-class AudioMixer;
-class AudioBuffer;
-class AudioResampler;
-
-
-// ----------------------------------------------------------------------------
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-
-// ----------------------------------------------------------------------------
-
-static const nsecs_t kStandbyTimeInNsecs = seconds(3);
-
-class AudioFlinger : public BnAudioFlinger, public IBinder::DeathRecipient
-{
-public:
-    static void instantiate();
-
-    virtual     status_t    dump(int fd, const Vector<String16>& args);
-
-    // IAudioFlinger interface
-    virtual sp<IAudioTrack> createTrack(
-                                pid_t pid,
-                                int streamType,
-                                uint32_t sampleRate,
-                                int format,
-                                int channelCount,
-                                int frameCount,
-                                uint32_t flags,
-                                const sp<IMemory>& sharedBuffer,
-                                int output,
-                                status_t *status);
-
-    virtual     uint32_t    sampleRate(int output) const;
-    virtual     int         channelCount(int output) const;
-    virtual     int         format(int output) const;
-    virtual     size_t      frameCount(int output) const;
-    virtual     uint32_t    latency(int output) const;
-
-    virtual     status_t    setMasterVolume(float value);
-    virtual     status_t    setMasterMute(bool muted);
-
-    virtual     float       masterVolume() const;
-    virtual     bool        masterMute() const;
-
-    virtual     status_t    setStreamVolume(int stream, float value, int output);
-    virtual     status_t    setStreamMute(int stream, bool muted);
-
-    virtual     float       streamVolume(int stream, int output) const;
-    virtual     bool        streamMute(int stream) const;
-
-    virtual     status_t    setMode(int mode);
-
-    virtual     status_t    setMicMute(bool state);
-    virtual     bool        getMicMute() const;
-
-    virtual     bool        isStreamActive(int stream) const;
-
-    virtual     status_t    setParameters(int ioHandle, const String8& keyValuePairs);
-    virtual     String8     getParameters(int ioHandle, const String8& keys);
-
-    virtual     void        registerClient(const sp<IAudioFlingerClient>& client);
-
-    virtual     size_t      getInputBufferSize(uint32_t sampleRate, int format, int channelCount);
-    virtual     unsigned int  getInputFramesLost(int ioHandle);
-
-    virtual int openOutput(uint32_t *pDevices,
-                                    uint32_t *pSamplingRate,
-                                    uint32_t *pFormat,
-                                    uint32_t *pChannels,
-                                    uint32_t *pLatencyMs,
-                                    uint32_t flags);
-
-    virtual int openDuplicateOutput(int output1, int output2);
-
-    virtual status_t closeOutput(int output);
-
-    virtual status_t suspendOutput(int output);
-
-    virtual status_t restoreOutput(int output);
-
-    virtual int openInput(uint32_t *pDevices,
-                            uint32_t *pSamplingRate,
-                            uint32_t *pFormat,
-                            uint32_t *pChannels,
-                            uint32_t acoustics);
-
-    virtual status_t closeInput(int input);
-
-    virtual status_t setStreamOutput(uint32_t stream, int output);
-
-    virtual status_t setVoiceVolume(float volume);
-
-    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames, int output);
-
-    // IBinder::DeathRecipient
-    virtual     void        binderDied(const wp<IBinder>& who);
-
-    enum hardware_call_state {
-        AUDIO_HW_IDLE = 0,
-        AUDIO_HW_INIT,
-        AUDIO_HW_OUTPUT_OPEN,
-        AUDIO_HW_OUTPUT_CLOSE,
-        AUDIO_HW_INPUT_OPEN,
-        AUDIO_HW_INPUT_CLOSE,
-        AUDIO_HW_STANDBY,
-        AUDIO_HW_SET_MASTER_VOLUME,
-        AUDIO_HW_GET_ROUTING,
-        AUDIO_HW_SET_ROUTING,
-        AUDIO_HW_GET_MODE,
-        AUDIO_HW_SET_MODE,
-        AUDIO_HW_GET_MIC_MUTE,
-        AUDIO_HW_SET_MIC_MUTE,
-        AUDIO_SET_VOICE_VOLUME,
-        AUDIO_SET_PARAMETER,
-    };
-
-    // record interface
-    virtual sp<IAudioRecord> openRecord(
-                                pid_t pid,
-                                int input,
-                                uint32_t sampleRate,
-                                int format,
-                                int channelCount,
-                                int frameCount,
-                                uint32_t flags,
-                                status_t *status);
-
-    virtual     status_t    onTransact(
-                                uint32_t code,
-                                const Parcel& data,
-                                Parcel* reply,
-                                uint32_t flags);
-
-private:
-                            AudioFlinger();
-    virtual                 ~AudioFlinger();
-
-
-    // Internal dump utilites.
-    status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
-    status_t dumpClients(int fd, const Vector<String16>& args);
-    status_t dumpInternals(int fd, const Vector<String16>& args);
-
-    // --- Client ---
-    class Client : public RefBase {
-    public:
-                            Client(const sp<AudioFlinger>& audioFlinger, pid_t pid);
-        virtual             ~Client();
-        const sp<MemoryDealer>&     heap() const;
-        pid_t               pid() const { return mPid; }
-        sp<AudioFlinger>    audioFlinger() { return mAudioFlinger; }
-
-    private:
-                            Client(const Client&);
-                            Client& operator = (const Client&);
-        sp<AudioFlinger>    mAudioFlinger;
-        sp<MemoryDealer>    mMemoryDealer;
-        pid_t               mPid;
-    };
-
-
-    class TrackHandle;
-    class RecordHandle;
-    class RecordThread;
-    class PlaybackThread;
-    class MixerThread;
-    class DirectOutputThread;
-    class DuplicatingThread;
-    class Track;
-    class RecordTrack;
-
-    class ThreadBase : public Thread {
-    public:
-        ThreadBase (const sp<AudioFlinger>& audioFlinger, int id);
-        virtual             ~ThreadBase();
-
-        status_t dumpBase(int fd, const Vector<String16>& args);
-
-        // base for record and playback
-        class TrackBase : public AudioBufferProvider, public RefBase {
-
-        public:
-            enum track_state {
-                IDLE,
-                TERMINATED,
-                STOPPED,
-                RESUMING,
-                ACTIVE,
-                PAUSING,
-                PAUSED
-            };
-
-            enum track_flags {
-                STEPSERVER_FAILED = 0x01, //  StepServer could not acquire cblk->lock mutex
-                SYSTEM_FLAGS_MASK = 0x0000ffffUL,
-                // The upper 16 bits are used for track-specific flags.
-            };
-
-                                TrackBase(const wp<ThreadBase>& thread,
-                                        const sp<Client>& client,
-                                        uint32_t sampleRate,
-                                        int format,
-                                        int channelCount,
-                                        int frameCount,
-                                        uint32_t flags,
-                                        const sp<IMemory>& sharedBuffer);
-                                ~TrackBase();
-
-            virtual status_t    start() = 0;
-            virtual void        stop() = 0;
-                    sp<IMemory> getCblk() const;
-                    audio_track_cblk_t* cblk() const { return mCblk; }
-
-        protected:
-            friend class ThreadBase;
-            friend class RecordHandle;
-            friend class PlaybackThread;
-            friend class RecordThread;
-            friend class MixerThread;
-            friend class DirectOutputThread;
-
-                                TrackBase(const TrackBase&);
-                                TrackBase& operator = (const TrackBase&);
-
-            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
-            virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
-
-            int format() const {
-                return mFormat;
-            }
-
-            int channelCount() const ;
-
-            int sampleRate() const;
-
-            void* getBuffer(uint32_t offset, uint32_t frames) const;
-
-            bool isStopped() const {
-                return mState == STOPPED;
-            }
-
-            bool isTerminated() const {
-                return mState == TERMINATED;
-            }
-
-            bool step();
-            void reset();
-
-            wp<ThreadBase>      mThread;
-            sp<Client>          mClient;
-            sp<IMemory>         mCblkMemory;
-            audio_track_cblk_t* mCblk;
-            void*               mBuffer;
-            void*               mBufferEnd;
-            uint32_t            mFrameCount;
-            // we don't really need a lock for these
-            int                 mState;
-            int                 mClientTid;
-            uint8_t             mFormat;
-            uint32_t            mFlags;
-        };
-
-        class ConfigEvent {
-        public:
-            ConfigEvent() : mEvent(0), mParam(0) {}
-
-            int mEvent;
-            int mParam;
-        };
-
-                    uint32_t    sampleRate() const;
-                    int         channelCount() const;
-                    int         format() const;
-                    size_t      frameCount() const;
-                    void        wakeUp()    { mWaitWorkCV.broadcast(); }
-                    void        exit();
-        virtual     bool        checkForNewParameters_l() = 0;
-        virtual     status_t    setParameters(const String8& keyValuePairs);
-        virtual     String8     getParameters(const String8& keys) = 0;
-        virtual     void        audioConfigChanged(int event, int param = 0) = 0;
-                    void        sendConfigEvent(int event, int param = 0);
-                    void        sendConfigEvent_l(int event, int param = 0);
-                    void        processConfigEvents();
-                    int         id() const { return mId;}
-                    bool        standby() { return mStandby; }
-
-        mutable     Mutex                   mLock;
-
-    protected:
-
-        friend class Track;
-        friend class TrackBase;
-        friend class PlaybackThread;
-        friend class MixerThread;
-        friend class DirectOutputThread;
-        friend class DuplicatingThread;
-        friend class RecordThread;
-        friend class RecordTrack;
-
-                    Condition               mWaitWorkCV;
-                    sp<AudioFlinger>        mAudioFlinger;
-                    uint32_t                mSampleRate;
-                    size_t                  mFrameCount;
-                    int                     mChannelCount;
-                    int                     mFormat;
-                    uint32_t                mFrameSize;
-                    Condition               mParamCond;
-                    Vector<String8>         mNewParameters;
-                    status_t                mParamStatus;
-                    Vector<ConfigEvent *>   mConfigEvents;
-                    bool                    mStandby;
-                    int                     mId;
-                    bool                    mExiting;
-    };
-
-    // --- PlaybackThread ---
-    class PlaybackThread : public ThreadBase {
-    public:
-
-        enum type {
-            MIXER,
-            DIRECT,
-            DUPLICATING
-        };
-
-        enum mixer_state {
-            MIXER_IDLE,
-            MIXER_TRACKS_ENABLED,
-            MIXER_TRACKS_READY
-        };
-
-        // playback track
-        class Track : public TrackBase {
-        public:
-                                Track(  const wp<ThreadBase>& thread,
-                                        const sp<Client>& client,
-                                        int streamType,
-                                        uint32_t sampleRate,
-                                        int format,
-                                        int channelCount,
-                                        int frameCount,
-                                        const sp<IMemory>& sharedBuffer);
-                                ~Track();
-
-                    void        dump(char* buffer, size_t size);
-            virtual status_t    start();
-            virtual void        stop();
-                    void        pause();
-
-                    void        flush();
-                    void        destroy();
-                    void        mute(bool);
-                    void        setVolume(float left, float right);
-                    int name() const {
-                        return mName;
-                    }
-
-                    int type() const {
-                        return mStreamType;
-                    }
-
-
-        protected:
-            friend class ThreadBase;
-            friend class AudioFlinger;
-            friend class TrackHandle;
-            friend class PlaybackThread;
-            friend class MixerThread;
-            friend class DirectOutputThread;
-
-                                Track(const Track&);
-                                Track& operator = (const Track&);
-
-            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-            bool isMuted() { return mMute; }
-            bool isPausing() const {
-                return mState == PAUSING;
-            }
-            bool isPaused() const {
-                return mState == PAUSED;
-            }
-            bool isReady() const;
-            void setPaused() { mState = PAUSED; }
-            void reset();
-
-            bool isOutputTrack() const {
-                return (mStreamType == AudioSystem::NUM_STREAM_TYPES);
-            }
-
-            // we don't really need a lock for these
-            float               mVolume[2];
-            volatile bool       mMute;
-            // FILLED state is used for suppressing volume ramp at begin of playing
-            enum {FS_FILLING, FS_FILLED, FS_ACTIVE};
-            mutable uint8_t     mFillingUpStatus;
-            int8_t              mRetryCount;
-            sp<IMemory>         mSharedBuffer;
-            bool                mResetDone;
-            int                 mStreamType;
-            int                 mName;
-        };  // end of Track
-
-
-        // playback track
-        class OutputTrack : public Track {
-        public:
-
-            class Buffer: public AudioBufferProvider::Buffer {
-            public:
-                int16_t *mBuffer;
-            };
-
-                                OutputTrack(  const wp<ThreadBase>& thread,
-                                        DuplicatingThread *sourceThread,
-                                        uint32_t sampleRate,
-                                        int format,
-                                        int channelCount,
-                                        int frameCount);
-                                ~OutputTrack();
-
-            virtual status_t    start();
-            virtual void        stop();
-                    bool        write(int16_t* data, uint32_t frames);
-                    bool        bufferQueueEmpty() { return (mBufferQueue.size() == 0) ? true : false; }
-                    bool        isActive() { return mActive; }
-            wp<ThreadBase>&     thread()  { return mThread; }
-
-        private:
-
-            status_t            obtainBuffer(AudioBufferProvider::Buffer* buffer, uint32_t waitTimeMs);
-            void                clearBufferQueue();
-
-            // Maximum number of pending buffers allocated by OutputTrack::write()
-            static const uint8_t kMaxOverFlowBuffers = 10;
-
-            Vector < Buffer* >          mBufferQueue;
-            AudioBufferProvider::Buffer mOutBuffer;
-            bool                        mActive;
-            DuplicatingThread*          mSourceThread;
-        };  // end of OutputTrack
-
-        PlaybackThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
-        virtual             ~PlaybackThread();
-
-        virtual     status_t    dump(int fd, const Vector<String16>& args);
-
-        // Thread virtuals
-        virtual     status_t    readyToRun();
-        virtual     void        onFirstRef();
-
-        virtual     uint32_t    latency() const;
-
-        virtual     status_t    setMasterVolume(float value);
-        virtual     status_t    setMasterMute(bool muted);
-
-        virtual     float       masterVolume() const;
-        virtual     bool        masterMute() const;
-
-        virtual     status_t    setStreamVolume(int stream, float value);
-        virtual     status_t    setStreamMute(int stream, bool muted);
-
-        virtual     float       streamVolume(int stream) const;
-        virtual     bool        streamMute(int stream) const;
-
-                    bool        isStreamActive(int stream) const;
-
-                    sp<Track>   createTrack_l(
-                                    const sp<AudioFlinger::Client>& client,
-                                    int streamType,
-                                    uint32_t sampleRate,
-                                    int format,
-                                    int channelCount,
-                                    int frameCount,
-                                    const sp<IMemory>& sharedBuffer,
-                                    status_t *status);
-
-                    AudioStreamOut* getOutput() { return mOutput; }
-
-        virtual     int         type() const { return mType; }
-                    void        suspend() { mSuspended++; }
-                    void        restore() { if (mSuspended) mSuspended--; }
-                    bool        isSuspended() { return (mSuspended != 0); }
-        virtual     String8     getParameters(const String8& keys);
-        virtual     void        audioConfigChanged(int event, int param = 0);
-        virtual     status_t    getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
-
-        struct  stream_type_t {
-            stream_type_t()
-                :   volume(1.0f),
-                    mute(false)
-            {
-            }
-            float       volume;
-            bool        mute;
-        };
-
-    protected:
-        int                             mType;
-        int16_t*                        mMixBuffer;
-        int                             mSuspended;
-        int                             mBytesWritten;
-        bool                            mMasterMute;
-        SortedVector< wp<Track> >       mActiveTracks;
-
-        virtual int             getTrackName_l() = 0;
-        virtual void            deleteTrackName_l(int name) = 0;
-        virtual uint32_t        activeSleepTimeUs() = 0;
-        virtual uint32_t        idleSleepTimeUs() = 0;
-
-    private:
-
-        friend class AudioFlinger;
-        friend class OutputTrack;
-        friend class Track;
-        friend class TrackBase;
-        friend class MixerThread;
-        friend class DirectOutputThread;
-        friend class DuplicatingThread;
-
-        PlaybackThread(const Client&);
-        PlaybackThread& operator = (const PlaybackThread&);
-
-        status_t    addTrack_l(const sp<Track>& track);
-        void        destroyTrack_l(const sp<Track>& track);
-
-        void        readOutputParameters();
-
-        virtual status_t    dumpInternals(int fd, const Vector<String16>& args);
-        status_t    dumpTracks(int fd, const Vector<String16>& args);
-
-        SortedVector< sp<Track> >       mTracks;
-        // mStreamTypes[] uses 1 additionnal stream type internally for the OutputTrack used by DuplicatingThread
-        stream_type_t                   mStreamTypes[AudioSystem::NUM_STREAM_TYPES + 1];
-        AudioStreamOut*                 mOutput;
-        float                           mMasterVolume;
-        nsecs_t                         mLastWriteTime;
-        int                             mNumWrites;
-        int                             mNumDelayedWrites;
-        bool                            mInWrite;
-    };
-
-    class MixerThread : public PlaybackThread {
-    public:
-        MixerThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
-        virtual             ~MixerThread();
-
-        // Thread virtuals
-        virtual     bool        threadLoop();
-
-                    void        getTracks(SortedVector < sp<Track> >& tracks,
-                                      SortedVector < wp<Track> >& activeTracks,
-                                      int streamType);
-                    void        putTracks(SortedVector < sp<Track> >& tracks,
-                                      SortedVector < wp<Track> >& activeTracks);
-        virtual     bool        checkForNewParameters_l();
-        virtual     status_t    dumpInternals(int fd, const Vector<String16>& args);
-
-    protected:
-                    uint32_t    prepareTracks_l(const SortedVector< wp<Track> >& activeTracks, Vector< sp<Track> > *tracksToRemove);
-        virtual     int         getTrackName_l();
-        virtual     void        deleteTrackName_l(int name);
-        virtual     uint32_t    activeSleepTimeUs();
-        virtual     uint32_t    idleSleepTimeUs();
-
-        AudioMixer*                     mAudioMixer;
-    };
-
-    class DirectOutputThread : public PlaybackThread {
-    public:
-
-        DirectOutputThread (const sp<AudioFlinger>& audioFlinger, AudioStreamOut* output, int id);
-        ~DirectOutputThread();
-
-        // Thread virtuals
-        virtual     bool        threadLoop();
-
-        virtual     bool        checkForNewParameters_l();
-
-    protected:
-        virtual     int         getTrackName_l();
-        virtual     void        deleteTrackName_l(int name);
-        virtual     uint32_t    activeSleepTimeUs();
-        virtual     uint32_t    idleSleepTimeUs();
-
-    private:
-        float mLeftVolume;
-        float mRightVolume;
-    };
-
-    class DuplicatingThread : public MixerThread {
-    public:
-        DuplicatingThread (const sp<AudioFlinger>& audioFlinger, MixerThread* mainThread, int id);
-        ~DuplicatingThread();
-
-        // Thread virtuals
-        virtual     bool        threadLoop();
-                    void        addOutputTrack(MixerThread* thread);
-                    void        removeOutputTrack(MixerThread* thread);
-                    uint32_t    waitTimeMs() { return mWaitTimeMs; }
-    protected:
-        virtual     uint32_t    activeSleepTimeUs();
-
-    private:
-                    bool        outputsReady(SortedVector< sp<OutputTrack> > &outputTracks);
-                    void        updateWaitTime();
-
-        SortedVector < sp<OutputTrack> >  mOutputTracks;
-                    uint32_t    mWaitTimeMs;
-    };
-
-              PlaybackThread *checkPlaybackThread_l(int output) const;
-              MixerThread *checkMixerThread_l(int output) const;
-              RecordThread *checkRecordThread_l(int input) const;
-              float streamVolumeInternal(int stream) const { return mStreamTypes[stream].volume; }
-              void audioConfigChanged_l(int event, int ioHandle, void *param2);
-
-    friend class AudioBuffer;
-
-    class TrackHandle : public android::BnAudioTrack {
-    public:
-                            TrackHandle(const sp<PlaybackThread::Track>& track);
-        virtual             ~TrackHandle();
-        virtual status_t    start();
-        virtual void        stop();
-        virtual void        flush();
-        virtual void        mute(bool);
-        virtual void        pause();
-        virtual void        setVolume(float left, float right);
-        virtual sp<IMemory> getCblk() const;
-        virtual status_t onTransact(
-            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-    private:
-        sp<PlaybackThread::Track> mTrack;
-    };
-
-    friend class Client;
-    friend class PlaybackThread::Track;
-
-
-                void        removeClient_l(pid_t pid);
-
-
-    // record thread
-    class RecordThread : public ThreadBase, public AudioBufferProvider
-    {
-    public:
-
-        // record track
-        class RecordTrack : public TrackBase {
-        public:
-                                RecordTrack(const wp<ThreadBase>& thread,
-                                        const sp<Client>& client,
-                                        uint32_t sampleRate,
-                                        int format,
-                                        int channelCount,
-                                        int frameCount,
-                                        uint32_t flags);
-                                ~RecordTrack();
-
-            virtual status_t    start();
-            virtual void        stop();
-
-                    bool        overflow() { bool tmp = mOverflow; mOverflow = false; return tmp; }
-                    bool        setOverflow() { bool tmp = mOverflow; mOverflow = true; return tmp; }
-
-                    void        dump(char* buffer, size_t size);
-        private:
-            friend class AudioFlinger;
-            friend class RecordThread;
-
-                                RecordTrack(const RecordTrack&);
-                                RecordTrack& operator = (const RecordTrack&);
-
-            virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
-
-            bool                mOverflow;
-        };
-
-
-                RecordThread(const sp<AudioFlinger>& audioFlinger,
-                        AudioStreamIn *input,
-                        uint32_t sampleRate,
-                        uint32_t channels,
-                        int id);
-                ~RecordThread();
-
-        virtual bool        threadLoop();
-        virtual status_t    readyToRun() { return NO_ERROR; }
-        virtual void        onFirstRef();
-
-                status_t    start(RecordTrack* recordTrack);
-                void        stop(RecordTrack* recordTrack);
-                status_t    dump(int fd, const Vector<String16>& args);
-                AudioStreamIn* getInput() { return mInput; }
-
-        virtual status_t    getNextBuffer(AudioBufferProvider::Buffer* buffer);
-        virtual void        releaseBuffer(AudioBufferProvider::Buffer* buffer);
-        virtual bool        checkForNewParameters_l();
-        virtual String8     getParameters(const String8& keys);
-        virtual void        audioConfigChanged(int event, int param = 0);
-                void        readInputParameters();
-        virtual unsigned int  getInputFramesLost();
-
-    private:
-                RecordThread();
-                AudioStreamIn                       *mInput;
-                sp<RecordTrack>                     mActiveTrack;
-                Condition                           mStartStopCond;
-                AudioResampler                      *mResampler;
-                int32_t                             *mRsmpOutBuffer;
-                int16_t                             *mRsmpInBuffer;
-                size_t                              mRsmpInIndex;
-                size_t                              mInputBytes;
-                int                                 mReqChannelCount;
-                uint32_t                            mReqSampleRate;
-                ssize_t                             mBytesRead;
-    };
-
-    class RecordHandle : public android::BnAudioRecord {
-    public:
-        RecordHandle(const sp<RecordThread::RecordTrack>& recordTrack);
-        virtual             ~RecordHandle();
-        virtual status_t    start();
-        virtual void        stop();
-        virtual sp<IMemory> getCblk() const;
-        virtual status_t onTransact(
-            uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-    private:
-        sp<RecordThread::RecordTrack> mRecordTrack;
-    };
-
-    friend class RecordThread;
-    friend class PlaybackThread;
-
-
-    mutable     Mutex                               mLock;
-
-                DefaultKeyedVector< pid_t, wp<Client> >     mClients;
-
-                mutable     Mutex                   mHardwareLock;
-                AudioHardwareInterface*             mAudioHardware;
-    mutable     int                                 mHardwareStatus;
-
-
-                DefaultKeyedVector< int, sp<PlaybackThread> >  mPlaybackThreads;
-                PlaybackThread::stream_type_t       mStreamTypes[AudioSystem::NUM_STREAM_TYPES];
-                float                               mMasterVolume;
-                bool                                mMasterMute;
-
-                DefaultKeyedVector< int, sp<RecordThread> >    mRecordThreads;
-
-                SortedVector< sp<IBinder> >         mNotificationClients;
-                int                                 mNextThreadId;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_FLINGER_H
diff --git a/libs/audioflinger/AudioHardwareGeneric.cpp b/libs/audioflinger/AudioHardwareGeneric.cpp
deleted file mode 100644
index d63c031..0000000
--- a/libs/audioflinger/AudioHardwareGeneric.cpp
+++ /dev/null
@@ -1,411 +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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sched.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-#define LOG_TAG "AudioHardware"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareGeneric.h"
-#include <media/AudioRecord.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-static char const * const kAudioDeviceName = "/dev/eac";
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareGeneric::AudioHardwareGeneric()
-    : mOutput(0), mInput(0),  mFd(-1), mMicMute(false)
-{
-    mFd = ::open(kAudioDeviceName, O_RDWR);
-}
-
-AudioHardwareGeneric::~AudioHardwareGeneric()
-{
-    if (mFd >= 0) ::close(mFd);
-    closeOutputStream((AudioStreamOut *)mOutput);
-    closeInputStream((AudioStreamIn *)mInput);
-}
-
-status_t AudioHardwareGeneric::initCheck()
-{
-    if (mFd >= 0) {
-        if (::access(kAudioDeviceName, O_RDWR) == NO_ERROR)
-            return NO_ERROR;
-    }
-    return NO_INIT;
-}
-
-AudioStreamOut* AudioHardwareGeneric::openOutputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
-    AutoMutex lock(mLock);
-
-    // only one output stream allowed
-    if (mOutput) {
-        if (status) {
-            *status = INVALID_OPERATION;
-        }
-        return 0;
-    }
-
-    // create new output stream
-    AudioStreamOutGeneric* out = new AudioStreamOutGeneric();
-    status_t lStatus = out->set(this, mFd, devices, format, channels, sampleRate);
-    if (status) {
-        *status = lStatus;
-    }
-    if (lStatus == NO_ERROR) {
-        mOutput = out;
-    } else {
-        delete out;
-    }
-    return mOutput;
-}
-
-void AudioHardwareGeneric::closeOutputStream(AudioStreamOut* out) {
-    if (mOutput && out == mOutput) {
-        delete mOutput;
-        mOutput = 0;
-    }
-}
-
-AudioStreamIn* AudioHardwareGeneric::openInputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
-        status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
-    // check for valid input source
-    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
-        return 0;
-    }
-
-    AutoMutex lock(mLock);
-
-    // only one input stream allowed
-    if (mInput) {
-        if (status) {
-            *status = INVALID_OPERATION;
-        }
-        return 0;
-    }
-
-    // create new output stream
-    AudioStreamInGeneric* in = new AudioStreamInGeneric();
-    status_t lStatus = in->set(this, mFd, devices, format, channels, sampleRate, acoustics);
-    if (status) {
-        *status = lStatus;
-    }
-    if (lStatus == NO_ERROR) {
-        mInput = in;
-    } else {
-        delete in;
-    }
-    return mInput;
-}
-
-void AudioHardwareGeneric::closeInputStream(AudioStreamIn* in) {
-    if (mInput && in == mInput) {
-        delete mInput;
-        mInput = 0;
-    }
-}
-
-status_t AudioHardwareGeneric::setVoiceVolume(float v)
-{
-    // Implement: set voice volume
-    return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::setMasterVolume(float v)
-{
-    // Implement: set master volume
-    // return error - software mixer will handle it
-    return INVALID_OPERATION;
-}
-
-status_t AudioHardwareGeneric::setMicMute(bool state)
-{
-    mMicMute = state;
-    return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::getMicMute(bool* state)
-{
-    *state = mMicMute;
-    return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::dumpInternals(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    result.append("AudioHardwareGeneric::dumpInternals\n");
-    snprintf(buffer, SIZE, "\tmFd: %d mMicMute: %s\n",  mFd, mMicMute? "true": "false");
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioHardwareGeneric::dump(int fd, const Vector<String16>& args)
-{
-    dumpInternals(fd, args);
-    if (mInput) {
-        mInput->dump(fd, args);
-    }
-    if (mOutput) {
-        mOutput->dump(fd, args);
-    }
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamOutGeneric::set(
-        AudioHardwareGeneric *hw,
-        int fd,
-        uint32_t devices,
-        int *pFormat,
-        uint32_t *pChannels,
-        uint32_t *pRate)
-{
-    int lFormat = pFormat ? *pFormat : 0;
-    uint32_t lChannels = pChannels ? *pChannels : 0;
-    uint32_t lRate = pRate ? *pRate : 0;
-
-    // fix up defaults
-    if (lFormat == 0) lFormat = format();
-    if (lChannels == 0) lChannels = channels();
-    if (lRate == 0) lRate = sampleRate();
-
-    // check values
-    if ((lFormat != format()) ||
-            (lChannels != channels()) ||
-            (lRate != sampleRate())) {
-        if (pFormat) *pFormat = format();
-        if (pChannels) *pChannels = channels();
-        if (pRate) *pRate = sampleRate();
-        return BAD_VALUE;
-    }
-
-    if (pFormat) *pFormat = lFormat;
-    if (pChannels) *pChannels = lChannels;
-    if (pRate) *pRate = lRate;
-
-    mAudioHardware = hw;
-    mFd = fd;
-    mDevice = devices;
-    return NO_ERROR;
-}
-
-AudioStreamOutGeneric::~AudioStreamOutGeneric()
-{
-}
-
-ssize_t AudioStreamOutGeneric::write(const void* buffer, size_t bytes)
-{
-    Mutex::Autolock _l(mLock);
-    return ssize_t(::write(mFd, buffer, bytes));
-}
-
-status_t AudioStreamOutGeneric::standby()
-{
-    // Implement: audio hardware to standby mode
-    return NO_ERROR;
-}
-
-status_t AudioStreamOutGeneric::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "AudioStreamOutGeneric::dump\n");
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tformat: %d\n", format());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioStreamOutGeneric::setParameters(const String8& keyValuePairs)
-{
-    AudioParameter param = AudioParameter(keyValuePairs);
-    String8 key = String8(AudioParameter::keyRouting);
-    status_t status = NO_ERROR;
-    int device;
-    LOGV("setParameters() %s", keyValuePairs.string());
-
-    if (param.getInt(key, device) == NO_ERROR) {
-        mDevice = device;
-        param.remove(key);
-    }
-
-    if (param.size()) {
-        status = BAD_VALUE;
-    }
-    return status;
-}
-
-String8 AudioStreamOutGeneric::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    String8 value;
-    String8 key = String8(AudioParameter::keyRouting);
-
-    if (param.get(key, value) == NO_ERROR) {
-        param.addInt(key, (int)mDevice);
-    }
-
-    LOGV("getParameters() %s", param.toString().string());
-    return param.toString();
-}
-
-status_t AudioStreamOutGeneric::getRenderPosition(uint32_t *dspFrames)
-{
-    return INVALID_OPERATION;
-}
-
-// ----------------------------------------------------------------------------
-
-// record functions
-status_t AudioStreamInGeneric::set(
-        AudioHardwareGeneric *hw,
-        int fd,
-        uint32_t devices,
-        int *pFormat,
-        uint32_t *pChannels,
-        uint32_t *pRate,
-        AudioSystem::audio_in_acoustics acoustics)
-{
-    if (pFormat == 0 || pChannels == 0 || pRate == 0) return BAD_VALUE;
-    LOGV("AudioStreamInGeneric::set(%p, %d, %d, %d, %u)", hw, fd, *pFormat, *pChannels, *pRate);
-    // check values
-    if ((*pFormat != format()) ||
-        (*pChannels != channels()) ||
-        (*pRate != sampleRate())) {
-        LOGE("Error opening input channel");
-        *pFormat = format();
-        *pChannels = channels();
-        *pRate = sampleRate();
-        return BAD_VALUE;
-    }
-
-    mAudioHardware = hw;
-    mFd = fd;
-    mDevice = devices;
-    return NO_ERROR;
-}
-
-AudioStreamInGeneric::~AudioStreamInGeneric()
-{
-}
-
-ssize_t AudioStreamInGeneric::read(void* buffer, ssize_t bytes)
-{
-    AutoMutex lock(mLock);
-    if (mFd < 0) {
-        LOGE("Attempt to read from unopened device");
-        return NO_INIT;
-    }
-    return ::read(mFd, buffer, bytes);
-}
-
-status_t AudioStreamInGeneric::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "AudioStreamInGeneric::dump\n");
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tformat: %d\n", format());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tdevice: %d\n", mDevice);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tmAudioHardware: %p\n", mAudioHardware);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tmFd: %d\n", mFd);
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioStreamInGeneric::setParameters(const String8& keyValuePairs)
-{
-    AudioParameter param = AudioParameter(keyValuePairs);
-    String8 key = String8(AudioParameter::keyRouting);
-    status_t status = NO_ERROR;
-    int device;
-    LOGV("setParameters() %s", keyValuePairs.string());
-
-    if (param.getInt(key, device) == NO_ERROR) {
-        mDevice = device;
-        param.remove(key);
-    }
-
-    if (param.size()) {
-        status = BAD_VALUE;
-    }
-    return status;
-}
-
-String8 AudioStreamInGeneric::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    String8 value;
-    String8 key = String8(AudioParameter::keyRouting);
-
-    if (param.get(key, value) == NO_ERROR) {
-        param.addInt(key, (int)mDevice);
-    }
-
-    LOGV("getParameters() %s", param.toString().string());
-    return param.toString();
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareGeneric.h b/libs/audioflinger/AudioHardwareGeneric.h
deleted file mode 100644
index aa4e78d..0000000
--- a/libs/audioflinger/AudioHardwareGeneric.h
+++ /dev/null
@@ -1,151 +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.
-*/
-
-#ifndef ANDROID_AUDIO_HARDWARE_GENERIC_H
-#define ANDROID_AUDIO_HARDWARE_GENERIC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioHardwareGeneric;
-
-class AudioStreamOutGeneric : public AudioStreamOut {
-public:
-                        AudioStreamOutGeneric() : mAudioHardware(0), mFd(-1) {}
-    virtual             ~AudioStreamOutGeneric();
-
-    virtual status_t    set(
-            AudioHardwareGeneric *hw,
-            int mFd,
-            uint32_t devices,
-            int *pFormat,
-            uint32_t *pChannels,
-            uint32_t *pRate);
-
-    virtual uint32_t    sampleRate() const { return 44100; }
-    virtual size_t      bufferSize() const { return 4096; }
-    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
-    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-    virtual uint32_t    latency() const { return 20; }
-    virtual status_t    setVolume(float left, float right) { return INVALID_OPERATION; }
-    virtual ssize_t     write(const void* buffer, size_t bytes);
-    virtual status_t    standby();
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    virtual status_t    setParameters(const String8& keyValuePairs);
-    virtual String8     getParameters(const String8& keys);
-    virtual status_t    getRenderPosition(uint32_t *dspFrames);
-
-private:
-    AudioHardwareGeneric *mAudioHardware;
-    Mutex   mLock;
-    int     mFd;
-    uint32_t mDevice;
-};
-
-class AudioStreamInGeneric : public AudioStreamIn {
-public:
-                        AudioStreamInGeneric() : mAudioHardware(0), mFd(-1) {}
-    virtual             ~AudioStreamInGeneric();
-
-    virtual status_t    set(
-            AudioHardwareGeneric *hw,
-            int mFd,
-            uint32_t devices,
-            int *pFormat,
-            uint32_t *pChannels,
-            uint32_t *pRate,
-            AudioSystem::audio_in_acoustics acoustics);
-
-    virtual uint32_t    sampleRate() const { return 8000; }
-    virtual size_t      bufferSize() const { return 320; }
-    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_IN_MONO; }
-    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-    virtual status_t    setGain(float gain) { return INVALID_OPERATION; }
-    virtual ssize_t     read(void* buffer, ssize_t bytes);
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    virtual status_t    standby() { return NO_ERROR; }
-    virtual status_t    setParameters(const String8& keyValuePairs);
-    virtual String8     getParameters(const String8& keys);
-    virtual unsigned int  getInputFramesLost() const { return 0; }
-
-private:
-    AudioHardwareGeneric *mAudioHardware;
-    Mutex   mLock;
-    int     mFd;
-    uint32_t mDevice;
-};
-
-
-class AudioHardwareGeneric : public AudioHardwareBase
-{
-public:
-                        AudioHardwareGeneric();
-    virtual             ~AudioHardwareGeneric();
-    virtual status_t    initCheck();
-    virtual status_t    setVoiceVolume(float volume);
-    virtual status_t    setMasterVolume(float volume);
-
-    // mic mute
-    virtual status_t    setMicMute(bool state);
-    virtual status_t    getMicMute(bool* state);
-
-    // create I/O streams
-    virtual AudioStreamOut* openOutputStream(
-            uint32_t devices,
-            int *format=0,
-            uint32_t *channels=0,
-            uint32_t *sampleRate=0,
-            status_t *status=0);
-    virtual    void        closeOutputStream(AudioStreamOut* out);
-
-    virtual AudioStreamIn* openInputStream(
-            uint32_t devices,
-            int *format,
-            uint32_t *channels,
-            uint32_t *sampleRate,
-            status_t *status,
-            AudioSystem::audio_in_acoustics acoustics);
-    virtual    void        closeInputStream(AudioStreamIn* in);
-
-            void            closeOutputStream(AudioStreamOutGeneric* out);
-            void            closeInputStream(AudioStreamInGeneric* in);
-protected:
-    virtual status_t        dump(int fd, const Vector<String16>& args);
-
-private:
-    status_t                dumpInternals(int fd, const Vector<String16>& args);
-
-    Mutex                   mLock;
-    AudioStreamOutGeneric   *mOutput;
-    AudioStreamInGeneric    *mInput;
-    int                     mFd;
-    bool                    mMicMute;
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_HARDWARE_GENERIC_H
diff --git a/libs/audioflinger/AudioHardwareInterface.cpp b/libs/audioflinger/AudioHardwareInterface.cpp
deleted file mode 100644
index 9a4a7f9..0000000
--- a/libs/audioflinger/AudioHardwareInterface.cpp
+++ /dev/null
@@ -1,182 +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.
-*/
-
-#include <cutils/properties.h>
-#include <string.h>
-#include <unistd.h>
-//#define LOG_NDEBUG 0
-
-#define LOG_TAG "AudioHardwareInterface"
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareStub.h"
-#include "AudioHardwareGeneric.h"
-#ifdef WITH_A2DP
-#include "A2dpAudioInterface.h"
-#endif
-
-#ifdef ENABLE_AUDIO_DUMP
-#include "AudioDumpInterface.h"
-#endif
-
-
-// change to 1 to log routing calls
-#define LOG_ROUTING_CALLS 1
-
-namespace android {
-
-#if LOG_ROUTING_CALLS
-static const char* routingModeStrings[] =
-{
-    "OUT OF RANGE",
-    "INVALID",
-    "CURRENT",
-    "NORMAL",
-    "RINGTONE",
-    "IN_CALL"
-};
-
-static const char* routeNone = "NONE";
-
-static const char* displayMode(int mode)
-{
-    if ((mode < -2) || (mode > 2))
-        return routingModeStrings[0];
-    return routingModeStrings[mode+3];
-}
-#endif
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareInterface* AudioHardwareInterface::create()
-{
-    /*
-     * FIXME: This code needs to instantiate the correct audio device
-     * interface. For now - we use compile-time switches.
-     */
-    AudioHardwareInterface* hw = 0;
-    char value[PROPERTY_VALUE_MAX];
-
-#ifdef GENERIC_AUDIO
-    hw = new AudioHardwareGeneric();
-#else
-    // if running in emulation - use the emulator driver
-    if (property_get("ro.kernel.qemu", value, 0)) {
-        LOGD("Running in emulation - using generic audio driver");
-        hw = new AudioHardwareGeneric();
-    }
-    else {
-        LOGV("Creating Vendor Specific AudioHardware");
-        hw = createAudioHardware();
-    }
-#endif
-    if (hw->initCheck() != NO_ERROR) {
-        LOGW("Using stubbed audio hardware. No sound will be produced.");
-        delete hw;
-        hw = new AudioHardwareStub();
-    }
-    
-#ifdef WITH_A2DP
-    hw = new A2dpAudioInterface(hw);
-#endif
-
-#ifdef ENABLE_AUDIO_DUMP
-    // This code adds a record of buffers in a file to write calls made by AudioFlinger.
-    // It replaces the current AudioHardwareInterface object by an intermediate one which
-    // will record buffers in a file (after sending them to hardware) for testing purpose.
-    // This feature is enabled by defining symbol ENABLE_AUDIO_DUMP.
-    // The output file is set with setParameters("test_cmd_file_name=<name>"). Pause are not recorded in the file.
-    LOGV("opening PCM dump interface");
-    hw = new AudioDumpInterface(hw);    // replace interface
-#endif
-    return hw;
-}
-
-AudioStreamOut::~AudioStreamOut()
-{
-}
-
-AudioStreamIn::~AudioStreamIn() {}
-
-AudioHardwareBase::AudioHardwareBase()
-{
-    mMode = 0;
-}
-
-status_t AudioHardwareBase::setMode(int mode)
-{
-#if LOG_ROUTING_CALLS
-    LOGD("setMode(%s)", displayMode(mode));
-#endif
-    if ((mode < 0) || (mode >= AudioSystem::NUM_MODES))
-        return BAD_VALUE;
-    if (mMode == mode)
-        return ALREADY_EXISTS;
-    mMode = mode;
-    return NO_ERROR;
-}
-
-// default implementation
-status_t AudioHardwareBase::setParameters(const String8& keyValuePairs)
-{
-    return NO_ERROR;
-}
-
-// default implementation
-String8 AudioHardwareBase::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    return param.toString();
-}
-
-// default implementation
-size_t AudioHardwareBase::getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
-{
-    if (sampleRate != 8000) {
-        LOGW("getInputBufferSize bad sampling rate: %d", sampleRate);
-        return 0;
-    }
-    if (format != AudioSystem::PCM_16_BIT) {
-        LOGW("getInputBufferSize bad format: %d", format);
-        return 0;
-    }
-    if (channelCount != 1) {
-        LOGW("getInputBufferSize bad channel count: %d", channelCount);
-        return 0;
-    }
-
-    return 320;
-}
-
-status_t AudioHardwareBase::dumpState(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "AudioHardwareBase::dumpState\n");
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tmMode: %d\n", mMode);
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    dump(fd, args);  // Dump the state of the concrete child.
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.cpp b/libs/audioflinger/AudioHardwareStub.cpp
deleted file mode 100644
index d481150..0000000
--- a/libs/audioflinger/AudioHardwareStub.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-/* //device/servers/AudioFlinger/AudioHardwareStub.cpp
-**
-** 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.
-*/
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <utils/String8.h>
-
-#include "AudioHardwareStub.h"
-#include <media/AudioRecord.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-AudioHardwareStub::AudioHardwareStub() : mMicMute(false)
-{
-}
-
-AudioHardwareStub::~AudioHardwareStub()
-{
-}
-
-status_t AudioHardwareStub::initCheck()
-{
-    return NO_ERROR;
-}
-
-AudioStreamOut* AudioHardwareStub::openOutputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate, status_t *status)
-{
-    AudioStreamOutStub* out = new AudioStreamOutStub();
-    status_t lStatus = out->set(format, channels, sampleRate);
-    if (status) {
-        *status = lStatus;
-    }
-    if (lStatus == NO_ERROR)
-        return out;
-    delete out;
-    return 0;
-}
-
-void AudioHardwareStub::closeOutputStream(AudioStreamOut* out)
-{
-    delete out;
-}
-
-AudioStreamIn* AudioHardwareStub::openInputStream(
-        uint32_t devices, int *format, uint32_t *channels, uint32_t *sampleRate,
-        status_t *status, AudioSystem::audio_in_acoustics acoustics)
-{
-    // check for valid input source
-    if (!AudioSystem::isInputDevice((AudioSystem::audio_devices)devices)) {
-        return 0;
-    }
-
-    AudioStreamInStub* in = new AudioStreamInStub();
-    status_t lStatus = in->set(format, channels, sampleRate, acoustics);
-    if (status) {
-        *status = lStatus;
-    }
-    if (lStatus == NO_ERROR)
-        return in;
-    delete in;
-    return 0;
-}
-
-void AudioHardwareStub::closeInputStream(AudioStreamIn* in)
-{
-    delete in;
-}
-
-status_t AudioHardwareStub::setVoiceVolume(float volume)
-{
-    return NO_ERROR;
-}
-
-status_t AudioHardwareStub::setMasterVolume(float volume)
-{
-    return NO_ERROR;
-}
-
-status_t AudioHardwareStub::dumpInternals(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    result.append("AudioHardwareStub::dumpInternals\n");
-    snprintf(buffer, SIZE, "\tmMicMute: %s\n", mMicMute? "true": "false");
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioHardwareStub::dump(int fd, const Vector<String16>& args)
-{
-    dumpInternals(fd, args);
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamOutStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate)
-{
-    if (pFormat) *pFormat = format();
-    if (pChannels) *pChannels = channels();
-    if (pRate) *pRate = sampleRate();
-
-    return NO_ERROR;
-}
-
-ssize_t AudioStreamOutStub::write(const void* buffer, size_t bytes)
-{
-    // fake timing for audio output
-    usleep(bytes * 1000000 / sizeof(int16_t) / AudioSystem::popCount(channels()) / sampleRate());
-    return bytes;
-}
-
-status_t AudioStreamOutStub::standby()
-{
-    return NO_ERROR;
-}
-
-status_t AudioStreamOutStub::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "AudioStreamOutStub::dump\n");
-    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
-    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
-    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
-    snprintf(buffer, SIZE, "\tformat: %d\n", format());
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-String8 AudioStreamOutStub::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    return param.toString();
-}
-
-status_t AudioStreamOutStub::getRenderPosition(uint32_t *dspFrames)
-{
-    return INVALID_OPERATION;
-}
-
-// ----------------------------------------------------------------------------
-
-status_t AudioStreamInStub::set(int *pFormat, uint32_t *pChannels, uint32_t *pRate,
-                AudioSystem::audio_in_acoustics acoustics)
-{
-    return NO_ERROR;
-}
-
-ssize_t AudioStreamInStub::read(void* buffer, ssize_t bytes)
-{
-    // fake timing for audio input
-    usleep(bytes * 1000000 / sizeof(int16_t) / AudioSystem::popCount(channels()) / sampleRate());
-    memset(buffer, 0, bytes);
-    return bytes;
-}
-
-status_t AudioStreamInStub::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "AudioStreamInStub::dump\n");
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tsample rate: %d\n", sampleRate());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tbuffer size: %d\n", bufferSize());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tchannels: %d\n", channels());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "\tformat: %d\n", format());
-    result.append(buffer);
-    ::write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-String8 AudioStreamInStub::getParameters(const String8& keys)
-{
-    AudioParameter param = AudioParameter(keys);
-    return param.toString();
-}
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioHardwareStub.h b/libs/audioflinger/AudioHardwareStub.h
deleted file mode 100644
index 06a29de..0000000
--- a/libs/audioflinger/AudioHardwareStub.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* //device/servers/AudioFlinger/AudioHardwareStub.h
-**
-** 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.
-*/
-
-#ifndef ANDROID_AUDIO_HARDWARE_STUB_H
-#define ANDROID_AUDIO_HARDWARE_STUB_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <hardware_legacy/AudioHardwareBase.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioStreamOutStub : public AudioStreamOut {
-public:
-    virtual status_t    set(int *pFormat, uint32_t *pChannels, uint32_t *pRate);
-    virtual uint32_t    sampleRate() const { return 44100; }
-    virtual size_t      bufferSize() const { return 4096; }
-    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_OUT_STEREO; }
-    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-    virtual uint32_t    latency() const { return 0; }
-    virtual status_t    setVolume(float left, float right) { return NO_ERROR; }
-    virtual ssize_t     write(const void* buffer, size_t bytes);
-    virtual status_t    standby();
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    virtual status_t    setParameters(const String8& keyValuePairs) { return NO_ERROR;}
-    virtual String8     getParameters(const String8& keys);
-    virtual status_t    getRenderPosition(uint32_t *dspFrames);
-};
-
-class AudioStreamInStub : public AudioStreamIn {
-public:
-    virtual status_t    set(int *pFormat, uint32_t *pChannels, uint32_t *pRate, AudioSystem::audio_in_acoustics acoustics);
-    virtual uint32_t    sampleRate() const { return 8000; }
-    virtual size_t      bufferSize() const { return 320; }
-    virtual uint32_t    channels() const { return AudioSystem::CHANNEL_IN_MONO; }
-    virtual int         format() const { return AudioSystem::PCM_16_BIT; }
-    virtual status_t    setGain(float gain) { return NO_ERROR; }
-    virtual ssize_t     read(void* buffer, ssize_t bytes);
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-    virtual status_t    standby() { return NO_ERROR; }
-    virtual status_t    setParameters(const String8& keyValuePairs) { return NO_ERROR;}
-    virtual String8     getParameters(const String8& keys);
-    virtual unsigned int  getInputFramesLost() const { return 0; }
-};
-
-class AudioHardwareStub : public  AudioHardwareBase
-{
-public:
-                        AudioHardwareStub();
-    virtual             ~AudioHardwareStub();
-    virtual status_t    initCheck();
-    virtual status_t    setVoiceVolume(float volume);
-    virtual status_t    setMasterVolume(float volume);
-
-    // mic mute
-    virtual status_t    setMicMute(bool state) { mMicMute = state;  return  NO_ERROR; }
-    virtual status_t    getMicMute(bool* state) { *state = mMicMute ; return NO_ERROR; }
-
-    // create I/O streams
-    virtual AudioStreamOut* openOutputStream(
-                                uint32_t devices,
-                                int *format=0,
-                                uint32_t *channels=0,
-                                uint32_t *sampleRate=0,
-                                status_t *status=0);
-    virtual    void        closeOutputStream(AudioStreamOut* out);
-
-    virtual AudioStreamIn* openInputStream(
-                                uint32_t devices,
-                                int *format,
-                                uint32_t *channels,
-                                uint32_t *sampleRate,
-                                status_t *status,
-                                AudioSystem::audio_in_acoustics acoustics);
-    virtual    void        closeInputStream(AudioStreamIn* in);
-
-protected:
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-
-            bool        mMicMute;
-private:
-    status_t            dumpInternals(int fd, const Vector<String16>& args);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_AUDIO_HARDWARE_STUB_H
diff --git a/libs/audioflinger/AudioMixer.cpp b/libs/audioflinger/AudioMixer.cpp
deleted file mode 100644
index 19a442a..0000000
--- a/libs/audioflinger/AudioMixer.cpp
+++ /dev/null
@@ -1,915 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioMixer.cpp
-**
-** 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.
-*/
-
-#define LOG_TAG "AudioMixer"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include "AudioMixer.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-static inline int16_t clamp16(int32_t sample)
-{
-    if ((sample>>15) ^ (sample>>31))
-        sample = 0x7FFF ^ (sample>>31);
-    return sample;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate)
-    :   mActiveTrack(0), mTrackNames(0), mSampleRate(sampleRate)
-{
-    mState.enabledTracks= 0;
-    mState.needsChanged = 0;
-    mState.frameCount   = frameCount;
-    mState.outputTemp   = 0;
-    mState.resampleTemp = 0;
-    mState.hook         = process__nop;
-    track_t* t = mState.tracks;
-    for (int i=0 ; i<32 ; i++) {
-        t->needs = 0;
-        t->volume[0] = UNITY_GAIN;
-        t->volume[1] = UNITY_GAIN;
-        t->volumeInc[0] = 0;
-        t->volumeInc[1] = 0;
-        t->channelCount = 2;
-        t->enabled = 0;
-        t->format = 16;
-        t->buffer.raw = 0;
-        t->bufferProvider = 0;
-        t->hook = 0;
-        t->resampler = 0;
-        t->sampleRate = mSampleRate;
-        t->in = 0;
-        t++;
-    }
-}
-
- AudioMixer::~AudioMixer()
- {
-     track_t* t = mState.tracks;
-     for (int i=0 ; i<32 ; i++) {
-         delete t->resampler;
-         t++;
-     }
-     delete [] mState.outputTemp;
-     delete [] mState.resampleTemp;
- }
-
- int AudioMixer::getTrackName()
- {
-    uint32_t names = mTrackNames;
-    uint32_t mask = 1;
-    int n = 0;
-    while (names & mask) {
-        mask <<= 1;
-        n++;
-    }
-    if (mask) {
-        LOGV("add track (%d)", n);
-        mTrackNames |= mask;
-        return TRACK0 + n;
-    }
-    return -1;
- }
-
- void AudioMixer::invalidateState(uint32_t mask)
- {
-    if (mask) {
-        mState.needsChanged |= mask;
-        mState.hook = process__validate;
-    }
- }
-
- void AudioMixer::deleteTrackName(int name)
- {
-    name -= TRACK0;
-    if (uint32_t(name) < MAX_NUM_TRACKS) {
-        LOGV("deleteTrackName(%d)", name);
-        track_t& track(mState.tracks[ name ]);
-        if (track.enabled != 0) {
-            track.enabled = 0;
-            invalidateState(1<<name);
-        }
-        if (track.resampler) {
-            // delete  the resampler
-            delete track.resampler;
-            track.resampler = 0;
-            track.sampleRate = mSampleRate;
-            invalidateState(1<<name);
-        }
-        track.volumeInc[0] = 0;
-        track.volumeInc[1] = 0;
-        mTrackNames &= ~(1<<name);
-    }
- }
-
-status_t AudioMixer::enable(int name)
-{
-    switch (name) {
-        case MIXING: {
-            if (mState.tracks[ mActiveTrack ].enabled != 1) {
-                mState.tracks[ mActiveTrack ].enabled = 1;
-                LOGV("enable(%d)", mActiveTrack);
-                invalidateState(1<<mActiveTrack);
-            }
-        } break;
-        default:
-            return NAME_NOT_FOUND;
-    }
-    return NO_ERROR;
-}
-
-status_t AudioMixer::disable(int name)
-{
-    switch (name) {
-        case MIXING: {
-            if (mState.tracks[ mActiveTrack ].enabled != 0) {
-                mState.tracks[ mActiveTrack ].enabled = 0;
-                LOGV("disable(%d)", mActiveTrack);
-                invalidateState(1<<mActiveTrack);
-            }
-        } break;
-        default:
-            return NAME_NOT_FOUND;
-    }
-    return NO_ERROR;
-}
-
-status_t AudioMixer::setActiveTrack(int track)
-{
-    if (uint32_t(track-TRACK0) >= MAX_NUM_TRACKS) {
-        return BAD_VALUE;
-    }
-    mActiveTrack = track - TRACK0;
-    return NO_ERROR;
-}
-
-status_t AudioMixer::setParameter(int target, int name, int value)
-{
-    switch (target) {
-    case TRACK:
-        if (name == CHANNEL_COUNT) {
-            if ((uint32_t(value) <= MAX_NUM_CHANNELS) && (value)) {
-                if (mState.tracks[ mActiveTrack ].channelCount != value) {
-                    mState.tracks[ mActiveTrack ].channelCount = value;
-                    LOGV("setParameter(TRACK, CHANNEL_COUNT, %d)", value);
-                    invalidateState(1<<mActiveTrack);
-                }
-                return NO_ERROR;
-            }
-        }
-        break;
-    case RESAMPLE:
-        if (name == SAMPLE_RATE) {
-            if (value > 0) {
-                track_t& track = mState.tracks[ mActiveTrack ];
-                if (track.setResampler(uint32_t(value), mSampleRate)) {
-                    LOGV("setParameter(RESAMPLE, SAMPLE_RATE, %u)",
-                            uint32_t(value));
-                    invalidateState(1<<mActiveTrack);
-                }
-                return NO_ERROR;
-            }
-        }
-        break;
-    case RAMP_VOLUME:
-    case VOLUME:
-        if ((uint32_t(name-VOLUME0) < MAX_NUM_CHANNELS)) {
-            track_t& track = mState.tracks[ mActiveTrack ];
-            if (track.volume[name-VOLUME0] != value) {
-                track.prevVolume[name-VOLUME0] = track.volume[name-VOLUME0] << 16;
-                track.volume[name-VOLUME0] = value;
-                if (target == VOLUME) {
-                    track.prevVolume[name-VOLUME0] = value << 16;
-                    track.volumeInc[name-VOLUME0] = 0;
-                } else {
-                    int32_t d = (value<<16) - track.prevVolume[name-VOLUME0];
-                    int32_t volInc = d / int32_t(mState.frameCount);
-                    track.volumeInc[name-VOLUME0] = volInc;
-                    if (volInc == 0) {
-                        track.prevVolume[name-VOLUME0] = value << 16;
-                    }
-                }
-                invalidateState(1<<mActiveTrack);
-            }
-            return NO_ERROR;
-        }
-        break;
-    }
-    return BAD_VALUE;
-}
-
-bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate)
-{
-    if (value!=devSampleRate || resampler) {
-        if (sampleRate != value) {
-            sampleRate = value;
-            if (resampler == 0) {
-                resampler = AudioResampler::create(
-                        format, channelCount, devSampleRate);
-            }
-            return true;
-        }
-    }
-    return false;
-}
-
-bool AudioMixer::track_t::doesResample() const
-{
-    return resampler != 0;
-}
-
-inline
-void AudioMixer::track_t::adjustVolumeRamp()
-{
-    for (int i=0 ; i<2 ; i++) {
-        if (((volumeInc[i]>0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) ||
-            ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) {
-            volumeInc[i] = 0;
-            prevVolume[i] = volume[i]<<16;
-        }
-    }
-}
-
-
-status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
-{
-    mState.tracks[ mActiveTrack ].bufferProvider = buffer;
-    return NO_ERROR;
-}
-
-
-
-void AudioMixer::process(void* output)
-{
-    mState.hook(&mState, output);
-}
-
-
-void AudioMixer::process__validate(state_t* state, void* output)
-{
-    LOGW_IF(!state->needsChanged,
-        "in process__validate() but nothing's invalid");
-
-    uint32_t changed = state->needsChanged;
-    state->needsChanged = 0; // clear the validation flag
-
-    // recompute which tracks are enabled / disabled
-    uint32_t enabled = 0;
-    uint32_t disabled = 0;
-    while (changed) {
-        const int i = 31 - __builtin_clz(changed);
-        const uint32_t mask = 1<<i;
-        changed &= ~mask;
-        track_t& t = state->tracks[i];
-        (t.enabled ? enabled : disabled) |= mask;
-    }
-    state->enabledTracks &= ~disabled;
-    state->enabledTracks |=  enabled;
-
-    // compute everything we need...
-    int countActiveTracks = 0;
-    int all16BitsStereoNoResample = 1;
-    int resampling = 0;
-    int volumeRamp = 0;
-    uint32_t en = state->enabledTracks;
-    while (en) {
-        const int i = 31 - __builtin_clz(en);
-        en &= ~(1<<i);
-
-        countActiveTracks++;
-        track_t& t = state->tracks[i];
-        uint32_t n = 0;
-        n |= NEEDS_CHANNEL_1 + t.channelCount - 1;
-        n |= NEEDS_FORMAT_16;
-        n |= t.doesResample() ? NEEDS_RESAMPLE_ENABLED : NEEDS_RESAMPLE_DISABLED;
-       
-        if (t.volumeInc[0]|t.volumeInc[1]) {
-            volumeRamp = 1;
-        } else if (!t.doesResample() && t.volumeRL == 0) {
-            n |= NEEDS_MUTE_ENABLED;
-        }
-        t.needs = n;
-
-        if ((n & NEEDS_MUTE__MASK) == NEEDS_MUTE_ENABLED) {
-            t.hook = track__nop;
-        } else {
-            if ((n & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
-                all16BitsStereoNoResample = 0;
-                resampling = 1;
-                t.hook = track__genericResample;
-            } else {
-                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_1){
-                    t.hook = track__16BitsMono;
-                    all16BitsStereoNoResample = 0;
-                }
-                if ((n & NEEDS_CHANNEL_COUNT__MASK) == NEEDS_CHANNEL_2){
-                    t.hook = track__16BitsStereo;
-                }
-            }
-        }
-    }
-
-    // select the processing hooks
-    state->hook = process__nop;
-    if (countActiveTracks) {
-        if (resampling) {
-            if (!state->outputTemp) {
-                state->outputTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
-            }
-            if (!state->resampleTemp) {
-                state->resampleTemp = new int32_t[MAX_NUM_CHANNELS * state->frameCount];
-            }
-            state->hook = process__genericResampling;
-        } else {
-            if (state->outputTemp) {
-                delete [] state->outputTemp;
-                state->outputTemp = 0;
-            }
-            if (state->resampleTemp) {
-                delete [] state->resampleTemp;
-                state->resampleTemp = 0;
-            }
-            state->hook = process__genericNoResampling;
-            if (all16BitsStereoNoResample && !volumeRamp) {
-                if (countActiveTracks == 1) {
-                    state->hook = process__OneTrack16BitsStereoNoResampling;
-                }
-            }
-        }
-    }
-
-    LOGV("mixer configuration change: %d activeTracks (%08x) "
-        "all16BitsStereoNoResample=%d, resampling=%d, volumeRamp=%d",
-        countActiveTracks, state->enabledTracks,
-        all16BitsStereoNoResample, resampling, volumeRamp);
-
-   state->hook(state, output);
-
-   // Now that the volume ramp has been done, set optimal state and
-   // track hooks for subsequent mixer process
-   if (countActiveTracks) {
-       int allMuted = 1;
-       uint32_t en = state->enabledTracks;
-       while (en) {
-           const int i = 31 - __builtin_clz(en);
-           en &= ~(1<<i);
-           track_t& t = state->tracks[i];
-           if (!t.doesResample() && t.volumeRL == 0)
-           {
-               t.needs |= NEEDS_MUTE_ENABLED;
-               t.hook = track__nop;
-           } else {
-               allMuted = 0;
-           }
-       }
-       if (allMuted) {
-           state->hook = process__nop;
-       } else if (!resampling && all16BitsStereoNoResample) {
-           if (countActiveTracks == 1) {
-              state->hook = process__OneTrack16BitsStereoNoResampling;
-           }
-       }
-   }
-}
-
-static inline
-int32_t mulAdd(int16_t in, int16_t v, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    asm( "smlabb %[out], %[in], %[v], %[a] \n"
-         : [out]"=r"(out)
-         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
-         : );
-    return out;
-#else
-    return a + in * int32_t(v);
-#endif
-}
-
-static inline
-int32_t mul(int16_t in, int16_t v)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    asm( "smulbb %[out], %[in], %[v] \n"
-         : [out]"=r"(out)
-         : [in]"%r"(in), [v]"r"(v)
-         : );
-    return out;
-#else
-    return in * int32_t(v);
-#endif
-}
-
-static inline
-int32_t mulAddRL(int left, uint32_t inRL, uint32_t vRL, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    if (left) {
-        asm( "smlabb %[out], %[inRL], %[vRL], %[a] \n"
-             : [out]"=r"(out)
-             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
-             : );
-    } else {
-        asm( "smlatt %[out], %[inRL], %[vRL], %[a] \n"
-             : [out]"=r"(out)
-             : [inRL]"%r"(inRL), [vRL]"r"(vRL), [a]"r"(a)
-             : );
-    }
-    return out;
-#else
-    if (left) {
-        return a + int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
-    } else {
-        return a + int16_t(inRL>>16) * int16_t(vRL>>16);
-    }
-#endif
-}
-
-static inline
-int32_t mulRL(int left, uint32_t inRL, uint32_t vRL)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    if (left) {
-        asm( "smulbb %[out], %[inRL], %[vRL] \n"
-             : [out]"=r"(out)
-             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
-             : );
-    } else {
-        asm( "smultt %[out], %[inRL], %[vRL] \n"
-             : [out]"=r"(out)
-             : [inRL]"%r"(inRL), [vRL]"r"(vRL)
-             : );
-    }
-    return out;
-#else
-    if (left) {
-        return int16_t(inRL&0xFFFF) * int16_t(vRL&0xFFFF);
-    } else {
-        return int16_t(inRL>>16) * int16_t(vRL>>16);
-    }
-#endif
-}
-
-
-void AudioMixer::track__genericResample(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
-{
-    t->resampler->setSampleRate(t->sampleRate);
-
-    // ramp gain - resample to temp buffer and scale/mix in 2nd step
-    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
-        t->resampler->setVolume(UNITY_GAIN, UNITY_GAIN);
-        memset(temp, 0, outFrameCount * MAX_NUM_CHANNELS * sizeof(int32_t));
-        t->resampler->resample(temp, outFrameCount, t->bufferProvider);
-        volumeRampStereo(t, out, outFrameCount, temp);
-    }
-
-    // constant gain
-    else {
-        t->resampler->setVolume(t->volume[0], t->volume[1]);
-        t->resampler->resample(out, outFrameCount, t->bufferProvider);
-    }
-}
-
-void AudioMixer::track__nop(track_t* t, int32_t* out, size_t outFrameCount, int32_t* temp)
-{
-}
-
-void AudioMixer::volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
-{
-    int32_t vl = t->prevVolume[0];
-    int32_t vr = t->prevVolume[1];
-    const int32_t vlInc = t->volumeInc[0];
-    const int32_t vrInc = t->volumeInc[1];
-
-    //LOGD("[0] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-    //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
-    //       (vl + vlInc*frameCount)/65536.0f, frameCount);
-   
-    // ramp volume
-    do {
-        *out++ += (vl >> 16) * (*temp++ >> 12);
-        *out++ += (vr >> 16) * (*temp++ >> 12);
-        vl += vlInc;
-        vr += vrInc;
-    } while (--frameCount);
-
-    t->prevVolume[0] = vl;
-    t->prevVolume[1] = vr;
-    t->adjustVolumeRamp();
-}
-
-void AudioMixer::track__16BitsStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
-{
-    int16_t const *in = static_cast<int16_t const *>(t->in);
-
-    // ramp gain
-    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
-        int32_t vl = t->prevVolume[0];
-        int32_t vr = t->prevVolume[1];
-        const int32_t vlInc = t->volumeInc[0];
-        const int32_t vrInc = t->volumeInc[1];
-
-        // LOGD("[1] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-        //        t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
-        //        (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-        do {
-            *out++ += (vl >> 16) * (int32_t) *in++;
-            *out++ += (vr >> 16) * (int32_t) *in++;
-            vl += vlInc;
-            vr += vrInc;
-        } while (--frameCount);
-       
-        t->prevVolume[0] = vl;
-        t->prevVolume[1] = vr;
-        t->adjustVolumeRamp();
-    }
-
-    // constant gain
-    else {
-        const uint32_t vrl = t->volumeRL;
-        do {
-            uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
-            in += 2;
-            out[0] = mulAddRL(1, rl, vrl, out[0]);
-            out[1] = mulAddRL(0, rl, vrl, out[1]);
-            out += 2;
-        } while (--frameCount);
-    }
-    t->in = in;
-}
-
-void AudioMixer::track__16BitsMono(track_t* t, int32_t* out, size_t frameCount, int32_t* temp)
-{
-    int16_t const *in = static_cast<int16_t const *>(t->in);
-
-    // ramp gain
-    if UNLIKELY(t->volumeInc[0]|t->volumeInc[1]) {
-        int32_t vl = t->prevVolume[0];
-        int32_t vr = t->prevVolume[1];
-        const int32_t vlInc = t->volumeInc[0];
-        const int32_t vrInc = t->volumeInc[1];
-
-        // LOGD("[2] %p: inc=%f, v0=%f, v1=%d, final=%f, count=%d",
-        //         t, vlInc/65536.0f, vl/65536.0f, t->volume[0],
-        //         (vl + vlInc*frameCount)/65536.0f, frameCount);
-
-        do {
-            int32_t l = *in++;
-            *out++ += (vl >> 16) * l;
-            *out++ += (vr >> 16) * l;
-            vl += vlInc;
-            vr += vrInc;
-        } while (--frameCount);
-       
-        t->prevVolume[0] = vl;
-        t->prevVolume[1] = vr;
-        t->adjustVolumeRamp();
-    }
-    // constant gain
-    else {
-        const int16_t vl = t->volume[0];
-        const int16_t vr = t->volume[1];
-        do {
-            int16_t l = *in++;
-            out[0] = mulAdd(l, vl, out[0]);
-            out[1] = mulAdd(l, vr, out[1]);
-            out += 2;
-        } while (--frameCount);
-    }
-    t->in = in;
-}
-
-void AudioMixer::ditherAndClamp(int32_t* out, int32_t const *sums, size_t c)
-{
-    for (size_t i=0 ; i<c ; i++) {
-        int32_t l = *sums++;
-        int32_t r = *sums++;
-        int32_t nl = l >> 12;
-        int32_t nr = r >> 12;
-        l = clamp16(nl);
-        r = clamp16(nr);
-        *out++ = (r<<16) | (l & 0xFFFF);
-    }
-}
-
-// no-op case
-void AudioMixer::process__nop(state_t* state, void* output)
-{
-    // this assumes output 16 bits stereo, no resampling
-    memset(output, 0, state->frameCount*4);
-    uint32_t en = state->enabledTracks;
-    while (en) {
-        const int i = 31 - __builtin_clz(en);
-        en &= ~(1<<i);
-        track_t& t = state->tracks[i];
-        size_t outFrames = state->frameCount;
-        while (outFrames) {
-            t.buffer.frameCount = outFrames;
-            t.bufferProvider->getNextBuffer(&t.buffer);
-            if (!t.buffer.raw) break;
-            outFrames -= t.buffer.frameCount;
-            t.bufferProvider->releaseBuffer(&t.buffer);
-        }
-    }
-}
-
-// generic code without resampling
-void AudioMixer::process__genericNoResampling(state_t* state, void* output)
-{
-    int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
-
-    // acquire each track's buffer
-    uint32_t enabledTracks = state->enabledTracks;
-    uint32_t en = enabledTracks;
-    while (en) {
-        const int i = 31 - __builtin_clz(en);
-        en &= ~(1<<i);
-        track_t& t = state->tracks[i];
-        t.buffer.frameCount = state->frameCount;
-        t.bufferProvider->getNextBuffer(&t.buffer);
-        t.frameCount = t.buffer.frameCount;
-        t.in = t.buffer.raw;
-        // t.in == NULL can happen if the track was flushed just after having
-        // been enabled for mixing.
-        if (t.in == NULL)
-            enabledTracks &= ~(1<<i);
-    }
-
-    // this assumes output 16 bits stereo, no resampling
-    int32_t* out = static_cast<int32_t*>(output);
-    size_t numFrames = state->frameCount;
-    do {
-        memset(outTemp, 0, sizeof(outTemp));
-
-        en = enabledTracks;
-        while (en) {
-            const int i = 31 - __builtin_clz(en);
-            en &= ~(1<<i);
-            track_t& t = state->tracks[i];
-            size_t outFrames = BLOCKSIZE;
-           
-            while (outFrames) {
-                size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
-                if (inFrames) {
-                    (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp);
-                    t.frameCount -= inFrames;
-                    outFrames -= inFrames;
-                }
-                if (t.frameCount == 0 && outFrames) {
-                    t.bufferProvider->releaseBuffer(&t.buffer);
-                    t.buffer.frameCount = numFrames - (BLOCKSIZE - outFrames);
-                    t.bufferProvider->getNextBuffer(&t.buffer);
-                    t.in = t.buffer.raw;
-                    if (t.in == NULL) {
-                        enabledTracks &= ~(1<<i);
-                        break;
-                    }
-                    t.frameCount = t.buffer.frameCount;
-                 }
-            }
-        }
-
-        ditherAndClamp(out, outTemp, BLOCKSIZE);
-        out += BLOCKSIZE;
-        numFrames -= BLOCKSIZE;
-    } while (numFrames);
-
-
-    // release each track's buffer
-    en = enabledTracks;
-    while (en) {
-        const int i = 31 - __builtin_clz(en);
-        en &= ~(1<<i);
-        track_t& t = state->tracks[i];
-        t.bufferProvider->releaseBuffer(&t.buffer);
-    }
-}
-
-// generic code with resampling
-void AudioMixer::process__genericResampling(state_t* state, void* output)
-{
-    int32_t* const outTemp = state->outputTemp;
-    const size_t size = sizeof(int32_t) * MAX_NUM_CHANNELS * state->frameCount;
-    memset(outTemp, 0, size);
-
-    int32_t* out = static_cast<int32_t*>(output);
-    size_t numFrames = state->frameCount;
-
-    uint32_t en = state->enabledTracks;
-    while (en) {
-        const int i = 31 - __builtin_clz(en);
-        en &= ~(1<<i);
-        track_t& t = state->tracks[i];
-
-        // this is a little goofy, on the resampling case we don't
-        // acquire/release the buffers because it's done by
-        // the resampler.
-        if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
-            (t.hook)(&t, outTemp, numFrames, state->resampleTemp);
-        } else {
-
-            size_t outFrames = numFrames;
-           
-            while (outFrames) {
-                t.buffer.frameCount = outFrames;
-                t.bufferProvider->getNextBuffer(&t.buffer);
-                t.in = t.buffer.raw;
-                // t.in == NULL can happen if the track was flushed just after having
-                // been enabled for mixing.
-                if (t.in == NULL) break;
-
-                (t.hook)(&t, outTemp + (numFrames-outFrames)*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp);
-                outFrames -= t.buffer.frameCount;
-                t.bufferProvider->releaseBuffer(&t.buffer);
-            }
-        }
-    }
-
-    ditherAndClamp(out, outTemp, numFrames);
-}
-
-// one track, 16 bits stereo without resampling is the most common case
-void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state, void* output)
-{
-    const int i = 31 - __builtin_clz(state->enabledTracks);
-    const track_t& t = state->tracks[i];
-
-    AudioBufferProvider::Buffer& b(t.buffer);
-   
-    int32_t* out = static_cast<int32_t*>(output);
-    size_t numFrames = state->frameCount;
-  
-    const int16_t vl = t.volume[0];
-    const int16_t vr = t.volume[1];
-    const uint32_t vrl = t.volumeRL;
-    while (numFrames) {
-        b.frameCount = numFrames;
-        t.bufferProvider->getNextBuffer(&b);
-        int16_t const *in = b.i16;
-
-        // in == NULL can happen if the track was flushed just after having
-        // been enabled for mixing.
-        if (in == NULL || ((unsigned long)in & 3)) {
-            memset(out, 0, numFrames*MAX_NUM_CHANNELS*sizeof(int16_t));
-            LOGE_IF(((unsigned long)in & 3), "process stereo track: input buffer alignment pb: buffer %p track %d, channels %d, needs %08x",
-                    in, i, t.channelCount, t.needs);
-            return;
-        }
-        size_t outFrames = b.frameCount;
-       
-        if (UNLIKELY(uint32_t(vl) > UNITY_GAIN || uint32_t(vr) > UNITY_GAIN)) {
-            // volume is boosted, so we might need to clamp even though
-            // we process only one track.
-            do {
-                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
-                in += 2;
-                int32_t l = mulRL(1, rl, vrl) >> 12;
-                int32_t r = mulRL(0, rl, vrl) >> 12;
-                // clamping...
-                l = clamp16(l);
-                r = clamp16(r);
-                *out++ = (r<<16) | (l & 0xFFFF);
-            } while (--outFrames);
-        } else {
-            do {
-                uint32_t rl = *reinterpret_cast<uint32_t const *>(in);
-                in += 2;
-                int32_t l = mulRL(1, rl, vrl) >> 12;
-                int32_t r = mulRL(0, rl, vrl) >> 12;
-                *out++ = (r<<16) | (l & 0xFFFF);
-            } while (--outFrames);
-        }
-        numFrames -= b.frameCount;
-        t.bufferProvider->releaseBuffer(&b);
-    }
-}
-
-// 2 tracks is also a common case
-void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output)
-{
-    int i;
-    uint32_t en = state->enabledTracks;
-
-    i = 31 - __builtin_clz(en);
-    const track_t& t0 = state->tracks[i];
-    AudioBufferProvider::Buffer& b0(t0.buffer);
-
-    en &= ~(1<<i);
-    i = 31 - __builtin_clz(en);
-    const track_t& t1 = state->tracks[i];
-    AudioBufferProvider::Buffer& b1(t1.buffer);
-   
-    int16_t const *in0;
-    const int16_t vl0 = t0.volume[0];
-    const int16_t vr0 = t0.volume[1];
-    size_t frameCount0 = 0;
-  
-    int16_t const *in1;
-    const int16_t vl1 = t1.volume[0];
-    const int16_t vr1 = t1.volume[1];
-    size_t frameCount1 = 0;
-   
-    int32_t* out = static_cast<int32_t*>(output);
-    size_t numFrames = state->frameCount;
-    int16_t const *buff = NULL;
-
-  
-    while (numFrames) {
-   
-        if (frameCount0 == 0) {
-            b0.frameCount = numFrames;
-            t0.bufferProvider->getNextBuffer(&b0);
-            if (b0.i16 == NULL) {
-                if (buff == NULL) {
-                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
-                }
-                in0 = buff;
-                b0.frameCount = numFrames;
-            } else {
-                in0 = b0.i16;
-            }
-            frameCount0 = b0.frameCount;
-        }
-        if (frameCount1 == 0) {
-            b1.frameCount = numFrames;
-            t1.bufferProvider->getNextBuffer(&b1);
-            if (b1.i16 == NULL) {
-                if (buff == NULL) {
-                    buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
-                }
-                in1 = buff;
-                b1.frameCount = numFrames;
-               } else {
-                in1 = b1.i16;
-            }
-            frameCount1 = b1.frameCount;
-        }
-       
-        size_t outFrames = frameCount0 < frameCount1?frameCount0:frameCount1;
-
-        numFrames -= outFrames;
-        frameCount0 -= outFrames;
-        frameCount1 -= outFrames;
-       
-        do {
-            int32_t l0 = *in0++;
-            int32_t r0 = *in0++;
-            l0 = mul(l0, vl0);
-            r0 = mul(r0, vr0);
-            int32_t l = *in1++;
-            int32_t r = *in1++;
-            l = mulAdd(l, vl1, l0) >> 12;
-            r = mulAdd(r, vr1, r0) >> 12;
-            // clamping...
-            l = clamp16(l);
-            r = clamp16(r);
-            *out++ = (r<<16) | (l & 0xFFFF);
-        } while (--outFrames);
-       
-        if (frameCount0 == 0) {
-            t0.bufferProvider->releaseBuffer(&b0);
-        }
-        if (frameCount1 == 0) {
-            t1.bufferProvider->releaseBuffer(&b1);
-        }
-    }   
-       
-    if (buff != NULL) {
-        delete [] buff;       
-    }
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/audioflinger/AudioMixer.h b/libs/audioflinger/AudioMixer.h
deleted file mode 100644
index 15766cd..0000000
--- a/libs/audioflinger/AudioMixer.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* //device/include/server/AudioFlinger/AudioMixer.h
-**
-** 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.
-*/
-
-#ifndef ANDROID_AUDIO_MIXER_H
-#define ANDROID_AUDIO_MIXER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "AudioBufferProvider.h"
-#include "AudioResampler.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ----------------------------------------------------------------------------
-
-class AudioMixer
-{
-public:
-                            AudioMixer(size_t frameCount, uint32_t sampleRate);
-
-                            ~AudioMixer();
-
-    static const uint32_t MAX_NUM_TRACKS = 32;
-    static const uint32_t MAX_NUM_CHANNELS = 2;
-
-    static const uint16_t UNITY_GAIN = 0x1000;
-
-    enum { // names
-
-        // track units (32 units)
-        TRACK0          = 0x1000,
-
-        // enable/disable
-        MIXING          = 0x2000,
-
-        // setParameter targets
-        TRACK           = 0x3000,
-        RESAMPLE        = 0x3001,
-        RAMP_VOLUME     = 0x3002, // ramp to new volume
-        VOLUME          = 0x3003, // don't ramp
-
-        // set Parameter names
-        // for target TRACK
-        CHANNEL_COUNT   = 0x4000,
-        FORMAT          = 0x4001,
-        // for TARGET RESAMPLE
-        SAMPLE_RATE     = 0x4100,
-        // for TARGET VOLUME (8 channels max)
-        VOLUME0         = 0x4200,
-        VOLUME1         = 0x4201,
-    };
-
-
-    int         getTrackName();
-    void        deleteTrackName(int name);
-
-    status_t    enable(int name);
-    status_t    disable(int name);
-
-    status_t    setActiveTrack(int track);
-    status_t    setParameter(int target, int name, int value);
-
-    status_t    setBufferProvider(AudioBufferProvider* bufferProvider);
-    void        process(void* output);
-
-    uint32_t    trackNames() const { return mTrackNames; }
-
-    static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);
-
-private:
-
-    enum {
-        NEEDS_CHANNEL_COUNT__MASK   = 0x00000003,
-        NEEDS_FORMAT__MASK          = 0x000000F0,
-        NEEDS_MUTE__MASK            = 0x00000100,
-        NEEDS_RESAMPLE__MASK        = 0x00001000,
-    };
-
-    enum {
-        NEEDS_CHANNEL_1             = 0x00000000,
-        NEEDS_CHANNEL_2             = 0x00000001,
-
-        NEEDS_FORMAT_16             = 0x00000010,
-
-        NEEDS_MUTE_DISABLED         = 0x00000000,
-        NEEDS_MUTE_ENABLED          = 0x00000100,
-
-        NEEDS_RESAMPLE_DISABLED     = 0x00000000,
-        NEEDS_RESAMPLE_ENABLED      = 0x00001000,
-    };
-
-    static inline int32_t applyVolume(int32_t in, int32_t v) {
-        return in * v;
-    }
-
-
-    struct state_t;
-
-    typedef void (*mix_t)(state_t* state, void* output);
-
-    static const int BLOCKSIZE = 16; // 4 cache lines
-
-    struct track_t {
-        uint32_t    needs;
-
-        union {
-        int16_t     volume[2];      // [0]3.12 fixed point
-        int32_t     volumeRL;
-        };
-
-        int32_t     prevVolume[2];
-
-        int32_t     volumeInc[2];
-
-        uint16_t    frameCount;
-
-        uint8_t     channelCount : 4;
-        uint8_t     enabled      : 1;
-        uint8_t     reserved0    : 3;
-        uint8_t     format;
-
-        AudioBufferProvider*                bufferProvider;
-        mutable AudioBufferProvider::Buffer buffer;
-
-        void (*hook)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp);
-        void const* in;             // current location in buffer
-
-        AudioResampler*     resampler;
-        uint32_t            sampleRate;
-
-        bool        setResampler(uint32_t sampleRate, uint32_t devSampleRate);
-        bool        doesResample() const;
-        void        adjustVolumeRamp();
-    };
-
-    // pad to 32-bytes to fill cache line
-    struct state_t {
-        uint32_t        enabledTracks;
-        uint32_t        needsChanged;
-        size_t          frameCount;
-        mix_t           hook;
-        int32_t         *outputTemp;
-        int32_t         *resampleTemp;
-        int32_t         reserved[2];
-        track_t         tracks[32]; __attribute__((aligned(32)));
-    };
-
-    int             mActiveTrack;
-    uint32_t        mTrackNames;
-    const uint32_t  mSampleRate;
-
-    state_t         mState __attribute__((aligned(32)));
-
-    void invalidateState(uint32_t mask);
-
-    static void track__genericResample(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
-    static void track__nop(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
-    static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp);
-    static void track__16BitsStereo(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
-    static void track__16BitsMono(track_t* t, int32_t* out, size_t numFrames, int32_t* temp);
-
-    static void process__validate(state_t* state, void* output);
-    static void process__nop(state_t* state, void* output);
-    static void process__genericNoResampling(state_t* state, void* output);
-    static void process__genericResampling(state_t* state, void* output);
-    static void process__OneTrack16BitsStereoNoResampling(state_t* state, void* output);
-    static void process__TwoTracks16BitsStereoNoResampling(state_t* state, void* output);
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif // ANDROID_AUDIO_MIXER_H
diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp
deleted file mode 100644
index c8b3f48..0000000
--- a/libs/audioflinger/AudioPolicyManagerBase.cpp
+++ /dev/null
@@ -1,1972 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "AudioPolicyManagerBase"
-//#define LOG_NDEBUG 0
-#include <utils/Log.h>
-#include <hardware_legacy/AudioPolicyManagerBase.h>
-#include <media/mediarecorder.h>
-
-namespace android {
-
-
-// ----------------------------------------------------------------------------
-// AudioPolicyInterface implementation
-// ----------------------------------------------------------------------------
-
-
-status_t AudioPolicyManagerBase::setDeviceConnectionState(AudioSystem::audio_devices device,
-                                                  AudioSystem::device_connection_state state,
-                                                  const char *device_address)
-{
-
-    LOGV("setDeviceConnectionState() device: %x, state %d, address %s", device, state, device_address);
-
-    // connect/disconnect only 1 device at a time
-    if (AudioSystem::popCount(device) != 1) return BAD_VALUE;
-
-    if (strlen(device_address) >= MAX_DEVICE_ADDRESS_LEN) {
-        LOGE("setDeviceConnectionState() invalid address: %s", device_address);
-        return BAD_VALUE;
-    }
-
-    // handle output devices
-    if (AudioSystem::isOutputDevice(device)) {
-
-#ifndef WITH_A2DP
-        if (AudioSystem::isA2dpDevice(device)) {
-            LOGE("setDeviceConnectionState() invalid device: %x", device);
-            return BAD_VALUE;
-        }
-#endif
-
-        switch (state)
-        {
-        // handle output device connection
-        case AudioSystem::DEVICE_STATE_AVAILABLE:
-            if (mAvailableOutputDevices & device) {
-                LOGW("setDeviceConnectionState() device already connected: %x", device);
-                return INVALID_OPERATION;
-            }
-            LOGV("setDeviceConnectionState() connecting device %x", device);
-
-            // register new device as available
-            mAvailableOutputDevices |= device;
-
-#ifdef WITH_A2DP
-            // handle A2DP device connection
-            if (AudioSystem::isA2dpDevice(device)) {
-                status_t status = handleA2dpConnection(device, device_address);
-                if (status != NO_ERROR) {
-                    mAvailableOutputDevices &= ~device;
-                    return status;
-                }
-            } else
-#endif
-            {
-                if (AudioSystem::isBluetoothScoDevice(device)) {
-                    LOGV("setDeviceConnectionState() BT SCO  device, address %s", device_address);
-                    // keep track of SCO device address
-                    mScoDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
-#ifdef WITH_A2DP
-                    if (mA2dpOutput != 0 &&
-                        mPhoneState != AudioSystem::MODE_NORMAL) {
-                        mpClientInterface->suspendOutput(mA2dpOutput);
-                    }
-#endif
-                }
-            }
-            break;
-        // handle output device disconnection
-        case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
-            if (!(mAvailableOutputDevices & device)) {
-                LOGW("setDeviceConnectionState() device not connected: %x", device);
-                return INVALID_OPERATION;
-            }
-
-
-            LOGV("setDeviceConnectionState() disconnecting device %x", device);
-            // remove device from available output devices
-            mAvailableOutputDevices &= ~device;
-
-#ifdef WITH_A2DP
-            // handle A2DP device disconnection
-            if (AudioSystem::isA2dpDevice(device)) {
-                status_t status = handleA2dpDisconnection(device, device_address);
-                if (status != NO_ERROR) {
-                    mAvailableOutputDevices |= device;
-                    return status;
-                }
-            } else
-#endif
-            {
-                if (AudioSystem::isBluetoothScoDevice(device)) {
-                    mScoDeviceAddress = "";
-#ifdef WITH_A2DP
-                    if (mA2dpOutput != 0 &&
-                        mPhoneState != AudioSystem::MODE_NORMAL) {
-                        mpClientInterface->restoreOutput(mA2dpOutput);
-                    }
-#endif
-                }
-            }
-            } break;
-
-        default:
-            LOGE("setDeviceConnectionState() invalid state: %x", state);
-            return BAD_VALUE;
-        }
-
-        // request routing change if necessary
-        uint32_t newDevice = getNewDevice(mHardwareOutput, false);
-#ifdef WITH_A2DP
-        checkOutputForAllStrategies(newDevice);
-        // A2DP outputs must be closed after checkOutputForAllStrategies() is executed
-        if (state == AudioSystem::DEVICE_STATE_UNAVAILABLE && AudioSystem::isA2dpDevice(device)) {
-            closeA2dpOutputs();
-        }
-#endif
-        updateDeviceForStrategy();
-        setOutputDevice(mHardwareOutput, newDevice);
-
-        if (device == AudioSystem::DEVICE_OUT_WIRED_HEADSET) {
-            device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
-        } else if (device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO ||
-                   device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET ||
-                   device == AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT) {
-            device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
-        } else {
-            return NO_ERROR;
-        }
-    }
-    // handle input devices
-    if (AudioSystem::isInputDevice(device)) {
-
-        switch (state)
-        {
-        // handle input device connection
-        case AudioSystem::DEVICE_STATE_AVAILABLE: {
-            if (mAvailableInputDevices & device) {
-                LOGW("setDeviceConnectionState() device already connected: %d", device);
-                return INVALID_OPERATION;
-            }
-            mAvailableInputDevices |= device;
-            }
-            break;
-
-        // handle input device disconnection
-        case AudioSystem::DEVICE_STATE_UNAVAILABLE: {
-            if (!(mAvailableInputDevices & device)) {
-                LOGW("setDeviceConnectionState() device not connected: %d", device);
-                return INVALID_OPERATION;
-            }
-            mAvailableInputDevices &= ~device;
-            } break;
-
-        default:
-            LOGE("setDeviceConnectionState() invalid state: %x", state);
-            return BAD_VALUE;
-        }
-
-        audio_io_handle_t activeInput = getActiveInput();
-        if (activeInput != 0) {
-            AudioInputDescriptor *inputDesc = mInputs.valueFor(activeInput);
-            uint32_t newDevice = getDeviceForInputSource(inputDesc->mInputSource);
-            if (newDevice != inputDesc->mDevice) {
-                LOGV("setDeviceConnectionState() changing device from %x to %x for input %d",
-                        inputDesc->mDevice, newDevice, activeInput);
-                inputDesc->mDevice = newDevice;
-                AudioParameter param = AudioParameter();
-                param.addInt(String8(AudioParameter::keyRouting), (int)newDevice);
-                mpClientInterface->setParameters(activeInput, param.toString());
-            }
-        }
-
-        return NO_ERROR;
-    }
-
-    LOGW("setDeviceConnectionState() invalid device: %x", device);
-    return BAD_VALUE;
-}
-
-AudioSystem::device_connection_state AudioPolicyManagerBase::getDeviceConnectionState(AudioSystem::audio_devices device,
-                                                  const char *device_address)
-{
-    AudioSystem::device_connection_state state = AudioSystem::DEVICE_STATE_UNAVAILABLE;
-    String8 address = String8(device_address);
-    if (AudioSystem::isOutputDevice(device)) {
-        if (device & mAvailableOutputDevices) {
-#ifdef WITH_A2DP
-            if (AudioSystem::isA2dpDevice(device) &&
-                address != "" && mA2dpDeviceAddress != address) {
-                return state;
-            }
-#endif
-            if (AudioSystem::isBluetoothScoDevice(device) &&
-                address != "" && mScoDeviceAddress != address) {
-                return state;
-            }
-            state = AudioSystem::DEVICE_STATE_AVAILABLE;
-        }
-    } else if (AudioSystem::isInputDevice(device)) {
-        if (device & mAvailableInputDevices) {
-            state = AudioSystem::DEVICE_STATE_AVAILABLE;
-        }
-    }
-
-    return state;
-}
-
-void AudioPolicyManagerBase::setPhoneState(int state)
-{
-    LOGV("setPhoneState() state %d", state);
-    uint32_t newDevice = 0;
-    if (state < 0 || state >= AudioSystem::NUM_MODES) {
-        LOGW("setPhoneState() invalid state %d", state);
-        return;
-    }
-
-    if (state == mPhoneState ) {
-        LOGW("setPhoneState() setting same state %d", state);
-        return;
-    }
-
-    // if leaving call state, handle special case of active streams
-    // pertaining to sonification strategy see handleIncallSonification()
-    if (mPhoneState == AudioSystem::MODE_IN_CALL) {
-        LOGV("setPhoneState() in call state management: new state is %d", state);
-        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
-            handleIncallSonification(stream, false, true);
-        }
-    }
-
-    // store previous phone state for management of sonification strategy below
-    int oldState = mPhoneState;
-    mPhoneState = state;
-    bool force = false;
-
-    // are we entering or starting a call
-    if ((oldState != AudioSystem::MODE_IN_CALL) && (state == AudioSystem::MODE_IN_CALL)) {
-        LOGV("  Entering call in setPhoneState()");
-        // force routing command to audio hardware when starting a call
-        // even if no device change is needed
-        force = true;
-    } else if ((oldState == AudioSystem::MODE_IN_CALL) && (state != AudioSystem::MODE_IN_CALL)) {
-        LOGV("  Exiting call in setPhoneState()");
-        // force routing command to audio hardware when exiting a call
-        // even if no device change is needed
-        force = true;
-    }
-
-    // check for device and output changes triggered by new phone state
-    newDevice = getNewDevice(mHardwareOutput, false);
-#ifdef WITH_A2DP
-    checkOutputForAllStrategies(newDevice);
-    // suspend A2DP output if a SCO device is present.
-    if (mA2dpOutput != 0 && mScoDeviceAddress != "") {
-        if (oldState == AudioSystem::MODE_NORMAL) {
-            mpClientInterface->suspendOutput(mA2dpOutput);
-        } else if (state == AudioSystem::MODE_NORMAL) {
-            mpClientInterface->restoreOutput(mA2dpOutput);
-        }
-    }
-#endif
-    updateDeviceForStrategy();
-
-    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
-
-    // force routing command to audio hardware when ending call
-    // even if no device change is needed
-    if (oldState == AudioSystem::MODE_IN_CALL && newDevice == 0) {
-        newDevice = hwOutputDesc->device();
-    }
-
-    // when changing from ring tone to in call mode, mute the ringing tone
-    // immediately and delay the route change to avoid sending the ring tone
-    // tail into the earpiece or headset.
-    int delayMs = 0;
-    if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
-        // delay the device change command by twice the output latency to have some margin
-        // and be sure that audio buffers not yet affected by the mute are out when
-        // we actually apply the route change
-        delayMs = hwOutputDesc->mLatency*2;
-        setStreamMute(AudioSystem::RING, true, mHardwareOutput);
-    }
-
-    // change routing is necessary
-    setOutputDevice(mHardwareOutput, newDevice, force, delayMs);
-
-    // if entering in call state, handle special case of active streams
-    // pertaining to sonification strategy see handleIncallSonification()
-    if (state == AudioSystem::MODE_IN_CALL) {
-        LOGV("setPhoneState() in call state management: new state is %d", state);
-        // unmute the ringing tone after a sufficient delay if it was muted before
-        // setting output device above
-        if (oldState == AudioSystem::MODE_RINGTONE) {
-            setStreamMute(AudioSystem::RING, false, mHardwareOutput, MUTE_TIME_MS);
-        }
-        for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
-            handleIncallSonification(stream, true, true);
-        }
-    }
-
-    // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
-    if (state == AudioSystem::MODE_RINGTONE &&
-        (hwOutputDesc->mRefCount[AudioSystem::MUSIC] ||
-        (systemTime() - mMusicStopTime) < seconds(SONIFICATION_HEADSET_MUSIC_DELAY))) {
-        mLimitRingtoneVolume = true;
-    } else {
-        mLimitRingtoneVolume = false;
-    }
-}
-
-void AudioPolicyManagerBase::setRingerMode(uint32_t mode, uint32_t mask)
-{
-    LOGV("setRingerMode() mode %x, mask %x", mode, mask);
-
-    mRingerMode = mode;
-}
-
-void AudioPolicyManagerBase::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
-{
-    LOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mPhoneState);
-
-    bool forceVolumeReeval = false;
-    switch(usage) {
-    case AudioSystem::FOR_COMMUNICATION:
-        if (config != AudioSystem::FORCE_SPEAKER && config != AudioSystem::FORCE_BT_SCO &&
-            config != AudioSystem::FORCE_NONE) {
-            LOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
-            return;
-        }
-        mForceUse[usage] = config;
-        break;
-    case AudioSystem::FOR_MEDIA:
-        if (config != AudioSystem::FORCE_HEADPHONES && config != AudioSystem::FORCE_BT_A2DP &&
-            config != AudioSystem::FORCE_WIRED_ACCESSORY && config != AudioSystem::FORCE_NONE) {
-            LOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
-            return;
-        }
-        mForceUse[usage] = config;
-        break;
-    case AudioSystem::FOR_RECORD:
-        if (config != AudioSystem::FORCE_BT_SCO && config != AudioSystem::FORCE_WIRED_ACCESSORY &&
-            config != AudioSystem::FORCE_NONE) {
-            LOGW("setForceUse() invalid config %d for FOR_RECORD", config);
-            return;
-        }
-        mForceUse[usage] = config;
-        break;
-    case AudioSystem::FOR_DOCK:
-        if (config != AudioSystem::FORCE_NONE && config != AudioSystem::FORCE_BT_CAR_DOCK &&
-            config != AudioSystem::FORCE_BT_DESK_DOCK && config != AudioSystem::FORCE_WIRED_ACCESSORY) {
-            LOGW("setForceUse() invalid config %d for FOR_DOCK", config);
-        }
-        forceVolumeReeval = true;
-        mForceUse[usage] = config;
-        break;
-    default:
-        LOGW("setForceUse() invalid usage %d", usage);
-        break;
-    }
-
-    // check for device and output changes triggered by new phone state
-    uint32_t newDevice = getNewDevice(mHardwareOutput, false);
-#ifdef WITH_A2DP
-    checkOutputForAllStrategies(newDevice);
-#endif
-    updateDeviceForStrategy();
-    setOutputDevice(mHardwareOutput, newDevice);
-    if (forceVolumeReeval) {
-        applyStreamVolumes(mHardwareOutput, newDevice);
-    }
-}
-
-AudioSystem::forced_config AudioPolicyManagerBase::getForceUse(AudioSystem::force_use usage)
-{
-    return mForceUse[usage];
-}
-
-void AudioPolicyManagerBase::setSystemProperty(const char* property, const char* value)
-{
-    LOGV("setSystemProperty() property %s, value %s", property, value);
-    if (strcmp(property, "ro.camera.sound.forced") == 0) {
-        if (atoi(value)) {
-            LOGV("ENFORCED_AUDIBLE cannot be muted");
-            mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = false;
-        } else {
-            LOGV("ENFORCED_AUDIBLE can be muted");
-            mStreams[AudioSystem::ENFORCED_AUDIBLE].mCanBeMuted = true;
-        }
-    }
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getOutput(AudioSystem::stream_type stream,
-                                    uint32_t samplingRate,
-                                    uint32_t format,
-                                    uint32_t channels,
-                                    AudioSystem::output_flags flags)
-{
-    audio_io_handle_t output = 0;
-    uint32_t latency = 0;
-    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
-    uint32_t device = getDeviceForStrategy(strategy);
-    LOGV("getOutput() stream %d, samplingRate %d, format %d, channels %x, flags %x", stream, samplingRate, format, channels, flags);
-
-#ifdef AUDIO_POLICY_TEST
-    if (mCurOutput != 0) {
-        LOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channels %x, mDirectOutput %d",
-                mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
-
-        if (mTestOutputs[mCurOutput] == 0) {
-            LOGV("getOutput() opening test output");
-            AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
-            outputDesc->mDevice = mTestDevice;
-            outputDesc->mSamplingRate = mTestSamplingRate;
-            outputDesc->mFormat = mTestFormat;
-            outputDesc->mChannels = mTestChannels;
-            outputDesc->mLatency = mTestLatencyMs;
-            outputDesc->mFlags = (AudioSystem::output_flags)(mDirectOutput ? AudioSystem::OUTPUT_FLAG_DIRECT : 0);
-            outputDesc->mRefCount[stream] = 0;
-            mTestOutputs[mCurOutput] = mpClientInterface->openOutput(&outputDesc->mDevice,
-                                            &outputDesc->mSamplingRate,
-                                            &outputDesc->mFormat,
-                                            &outputDesc->mChannels,
-                                            &outputDesc->mLatency,
-                                            outputDesc->mFlags);
-            if (mTestOutputs[mCurOutput]) {
-                AudioParameter outputCmd = AudioParameter();
-                outputCmd.addInt(String8("set_id"),mCurOutput);
-                mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
-                addOutput(mTestOutputs[mCurOutput], outputDesc);
-            }
-        }
-        return mTestOutputs[mCurOutput];
-    }
-#endif //AUDIO_POLICY_TEST
-
-    // open a direct output if required by specified parameters
-    if (needsDirectOuput(stream, samplingRate, format, channels, flags, device)) {
-
-        LOGV("getOutput() opening direct output device %x", device);
-        AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
-        outputDesc->mDevice = device;
-        outputDesc->mSamplingRate = samplingRate;
-        outputDesc->mFormat = format;
-        outputDesc->mChannels = channels;
-        outputDesc->mLatency = 0;
-        outputDesc->mFlags = (AudioSystem::output_flags)(flags | AudioSystem::OUTPUT_FLAG_DIRECT);
-        outputDesc->mRefCount[stream] = 0;
-        output = mpClientInterface->openOutput(&outputDesc->mDevice,
-                                        &outputDesc->mSamplingRate,
-                                        &outputDesc->mFormat,
-                                        &outputDesc->mChannels,
-                                        &outputDesc->mLatency,
-                                        outputDesc->mFlags);
-
-        // only accept an output with the requeted parameters
-        if (output == 0 ||
-            (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
-            (format != 0 && format != outputDesc->mFormat) ||
-            (channels != 0 && channels != outputDesc->mChannels)) {
-            LOGV("getOutput() failed opening direct output: samplingRate %d, format %d, channels %d",
-                    samplingRate, format, channels);
-            if (output != 0) {
-                mpClientInterface->closeOutput(output);
-            }
-            delete outputDesc;
-            return 0;
-        }
-        addOutput(output, outputDesc);
-        return output;
-    }
-
-    if (channels != 0 && channels != AudioSystem::CHANNEL_OUT_MONO &&
-        channels != AudioSystem::CHANNEL_OUT_STEREO) {
-        return 0;
-    }
-    // open a non direct output
-
-    // get which output is suitable for the specified stream. The actual routing change will happen
-    // when startOutput() will be called
-    uint32_t a2dpDevice = device & AudioSystem::DEVICE_OUT_ALL_A2DP;
-    if (AudioSystem::popCount((AudioSystem::audio_devices)device) == 2) {
-#ifdef WITH_A2DP
-        if (a2dpUsedForSonification() && a2dpDevice != 0) {
-            // if playing on 2 devices among which one is A2DP, use duplicated output
-            LOGV("getOutput() using duplicated output");
-            LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device in multiple %x selected but A2DP output not opened", device);
-            output = mDuplicatedOutput;
-        } else
-#endif
-        {
-            // if playing on 2 devices among which none is A2DP, use hardware output
-            output = mHardwareOutput;
-        }
-        LOGV("getOutput() using output %d for 2 devices %x", output, device);
-    } else {
-#ifdef WITH_A2DP
-        if (a2dpDevice != 0) {
-            // if playing on A2DP device, use a2dp output
-            LOGW_IF((mA2dpOutput == 0), "getOutput() A2DP device %x selected but A2DP output not opened", device);
-            output = mA2dpOutput;
-        } else
-#endif
-        {
-            // if playing on not A2DP device, use hardware output
-            output = mHardwareOutput;
-        }
-    }
-
-
-    LOGW_IF((output ==0), "getOutput() could not find output for stream %d, samplingRate %d, format %d, channels %x, flags %x",
-                stream, samplingRate, format, channels, flags);
-
-    return output;
-}
-
-status_t AudioPolicyManagerBase::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
-{
-    LOGV("startOutput() output %d, stream %d", output, stream);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        LOGW("startOutput() unknow output %d", output);
-        return BAD_VALUE;
-    }
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
-
-#ifdef WITH_A2DP
-    if (mA2dpOutput != 0  && !a2dpUsedForSonification() && strategy == STRATEGY_SONIFICATION) {
-        setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
-    }
-#endif
-
-    // incremenent usage count for this stream on the requested output:
-    // NOTE that the usage count is the same for duplicated output and hardware output which is
-    // necassary for a correct control of hardware output routing by startOutput() and stopOutput()
-    outputDesc->changeRefCount(stream, 1);
-
-    setOutputDevice(output, getNewDevice(output));
-
-    // handle special case for sonification while in call
-    if (mPhoneState == AudioSystem::MODE_IN_CALL) {
-        handleIncallSonification(stream, true, false);
-    }
-
-    // apply volume rules for current stream and device if necessary
-    checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, outputDesc->device());
-
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
-{
-    LOGV("stopOutput() output %d, stream %d", output, stream);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        LOGW("stopOutput() unknow output %d", output);
-        return BAD_VALUE;
-    }
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-    routing_strategy strategy = getStrategy((AudioSystem::stream_type)stream);
-
-    // handle special case for sonification while in call
-    if (mPhoneState == AudioSystem::MODE_IN_CALL) {
-        handleIncallSonification(stream, false, false);
-    }
-
-    if (outputDesc->mRefCount[stream] > 0) {
-        // decrement usage count of this stream on the output
-        outputDesc->changeRefCount(stream, -1);
-        // store time at which the last music track was stopped - see computeVolume()
-        if (stream == AudioSystem::MUSIC) {
-            mMusicStopTime = systemTime();
-        }
-
-        setOutputDevice(output, getNewDevice(output));
-
-#ifdef WITH_A2DP
-        if (mA2dpOutput != 0 && !a2dpUsedForSonification() && strategy == STRATEGY_SONIFICATION) {
-            setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput, mOutputs.valueFor(mHardwareOutput)->mLatency*2);
-        }
-#endif
-        if (output != mHardwareOutput) {
-            setOutputDevice(mHardwareOutput, getNewDevice(mHardwareOutput), true);
-        }
-        return NO_ERROR;
-    } else {
-        LOGW("stopOutput() refcount is already 0 for output %d", output);
-        return INVALID_OPERATION;
-    }
-}
-
-void AudioPolicyManagerBase::releaseOutput(audio_io_handle_t output)
-{
-    LOGV("releaseOutput() %d", output);
-    ssize_t index = mOutputs.indexOfKey(output);
-    if (index < 0) {
-        LOGW("releaseOutput() releasing unknown output %d", output);
-        return;
-    }
-
-#ifdef AUDIO_POLICY_TEST
-    int testIndex = testOutputIndex(output);
-    if (testIndex != 0) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueAt(index);
-        if (outputDesc->refCount() == 0) {
-            mpClientInterface->closeOutput(output);
-            delete mOutputs.valueAt(index);
-            mOutputs.removeItem(output);
-            mTestOutputs[testIndex] = 0;
-        }
-        return;
-    }
-#endif //AUDIO_POLICY_TEST
-
-    if (mOutputs.valueAt(index)->mFlags & AudioSystem::OUTPUT_FLAG_DIRECT) {
-        mpClientInterface->closeOutput(output);
-        delete mOutputs.valueAt(index);
-        mOutputs.removeItem(output);
-    }
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getInput(int inputSource,
-                                    uint32_t samplingRate,
-                                    uint32_t format,
-                                    uint32_t channels,
-                                    AudioSystem::audio_in_acoustics acoustics)
-{
-    audio_io_handle_t input = 0;
-    uint32_t device = getDeviceForInputSource(inputSource);
-
-    LOGV("getInput() inputSource %d, samplingRate %d, format %d, channels %x, acoustics %x", inputSource, samplingRate, format, channels, acoustics);
-
-    if (device == 0) {
-        return 0;
-    }
-
-    // adapt channel selection to input source
-    switch(inputSource) {
-    case AUDIO_SOURCE_VOICE_UPLINK:
-        channels = AudioSystem::CHANNEL_IN_VOICE_UPLINK;
-        break;
-    case AUDIO_SOURCE_VOICE_DOWNLINK:
-        channels = AudioSystem::CHANNEL_IN_VOICE_DNLINK;
-        break;
-    case AUDIO_SOURCE_VOICE_CALL:
-        channels = (AudioSystem::CHANNEL_IN_VOICE_UPLINK | AudioSystem::CHANNEL_IN_VOICE_DNLINK);
-        break;
-    default:
-        break;
-    }
-
-    AudioInputDescriptor *inputDesc = new AudioInputDescriptor();
-
-    inputDesc->mInputSource = inputSource;
-    inputDesc->mDevice = device;
-    inputDesc->mSamplingRate = samplingRate;
-    inputDesc->mFormat = format;
-    inputDesc->mChannels = channels;
-    inputDesc->mAcoustics = acoustics;
-    inputDesc->mRefCount = 0;
-    input = mpClientInterface->openInput(&inputDesc->mDevice,
-                                    &inputDesc->mSamplingRate,
-                                    &inputDesc->mFormat,
-                                    &inputDesc->mChannels,
-                                    inputDesc->mAcoustics);
-
-    // only accept input with the exact requested set of parameters
-    if (input == 0 ||
-        (samplingRate != inputDesc->mSamplingRate) ||
-        (format != inputDesc->mFormat) ||
-        (channels != inputDesc->mChannels)) {
-        LOGV("getInput() failed opening input: samplingRate %d, format %d, channels %d",
-                samplingRate, format, channels);
-        if (input != 0) {
-            mpClientInterface->closeInput(input);
-        }
-        delete inputDesc;
-        return 0;
-    }
-    mInputs.add(input, inputDesc);
-    return input;
-}
-
-status_t AudioPolicyManagerBase::startInput(audio_io_handle_t input)
-{
-    LOGV("startInput() input %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        LOGW("startInput() unknow input %d", input);
-        return BAD_VALUE;
-    }
-    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
-
-#ifdef AUDIO_POLICY_TEST
-    if (mTestInput == 0)
-#endif //AUDIO_POLICY_TEST
-    {
-        // refuse 2 active AudioRecord clients at the same time
-        if (getActiveInput() != 0) {
-            LOGW("startInput() input %d failed: other input already started", input);
-            return INVALID_OPERATION;
-        }
-    }
-
-    AudioParameter param = AudioParameter();
-    param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
-
-    // use Voice Recognition mode or not for this input based on input source
-    int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
-    param.addInt(String8("vr_mode"), vr_enabled);
-    LOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
-
-    mpClientInterface->setParameters(input, param.toString());
-
-    inputDesc->mRefCount = 1;
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::stopInput(audio_io_handle_t input)
-{
-    LOGV("stopInput() input %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        LOGW("stopInput() unknow input %d", input);
-        return BAD_VALUE;
-    }
-    AudioInputDescriptor *inputDesc = mInputs.valueAt(index);
-
-    if (inputDesc->mRefCount == 0) {
-        LOGW("stopInput() input %d already stopped", input);
-        return INVALID_OPERATION;
-    } else {
-        AudioParameter param = AudioParameter();
-        param.addInt(String8(AudioParameter::keyRouting), 0);
-        mpClientInterface->setParameters(input, param.toString());
-        inputDesc->mRefCount = 0;
-        return NO_ERROR;
-    }
-}
-
-void AudioPolicyManagerBase::releaseInput(audio_io_handle_t input)
-{
-    LOGV("releaseInput() %d", input);
-    ssize_t index = mInputs.indexOfKey(input);
-    if (index < 0) {
-        LOGW("releaseInput() releasing unknown input %d", input);
-        return;
-    }
-    mpClientInterface->closeInput(input);
-    delete mInputs.valueAt(index);
-    mInputs.removeItem(input);
-    LOGV("releaseInput() exit");
-}
-
-void AudioPolicyManagerBase::initStreamVolume(AudioSystem::stream_type stream,
-                                            int indexMin,
-                                            int indexMax)
-{
-    LOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
-    if (indexMin < 0 || indexMin >= indexMax) {
-        LOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", stream , indexMin, indexMax);
-        return;
-    }
-    mStreams[stream].mIndexMin = indexMin;
-    mStreams[stream].mIndexMax = indexMax;
-}
-
-status_t AudioPolicyManagerBase::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
-{
-
-    if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {
-        return BAD_VALUE;
-    }
-
-    // Force max volume if stream cannot be muted
-    if (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;
-
-    LOGV("setStreamVolumeIndex() stream %d, index %d", stream, index);
-    mStreams[stream].mIndexCur = index;
-
-    // compute and apply stream volume on all outputs according to connected device
-    status_t status = NO_ERROR;
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        status_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), mOutputs.valueAt(i)->device());
-        if (volStatus != NO_ERROR) {
-            status = volStatus;
-        }
-    }
-    return status;
-}
-
-status_t AudioPolicyManagerBase::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
-{
-    if (index == 0) {
-        return BAD_VALUE;
-    }
-    LOGV("getStreamVolumeIndex() stream %d", stream);
-    *index =  mStreams[stream].mIndexCur;
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "\nAudioPolicyManager Dump: %p\n", this);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Hardware Output: %d\n", mHardwareOutput);
-    result.append(buffer);
-#ifdef WITH_A2DP
-    snprintf(buffer, SIZE, " A2DP Output: %d\n", mA2dpOutput);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Duplicated Output: %d\n", mDuplicatedOutput);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " A2DP device address: %s\n", mA2dpDeviceAddress.string());
-    result.append(buffer);
-#endif
-    snprintf(buffer, SIZE, " SCO device address: %s\n", mScoDeviceAddress.string());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Output devices: %08x\n", mAvailableOutputDevices);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Input devices: %08x\n", mAvailableInputDevices);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Phone state: %d\n", mPhoneState);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Ringer mode: %d\n", mRingerMode);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for communications %d\n", mForceUse[AudioSystem::FOR_COMMUNICATION]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for media %d\n", mForceUse[AudioSystem::FOR_MEDIA]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for record %d\n", mForceUse[AudioSystem::FOR_RECORD]);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Force use for dock %d\n", mForceUse[AudioSystem::FOR_DOCK]);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    snprintf(buffer, SIZE, "\nOutputs dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mOutputs.size(); i++) {
-        snprintf(buffer, SIZE, "- Output %d dump:\n", mOutputs.keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        mOutputs.valueAt(i)->dump(fd);
-    }
-
-    snprintf(buffer, SIZE, "\nInputs dump:\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        snprintf(buffer, SIZE, "- Input %d dump:\n", mInputs.keyAt(i));
-        write(fd, buffer, strlen(buffer));
-        mInputs.valueAt(i)->dump(fd);
-    }
-
-    snprintf(buffer, SIZE, "\nStreams dump:\n");
-    write(fd, buffer, strlen(buffer));
-    snprintf(buffer, SIZE, " Stream  Index Min  Index Max  Index Cur  Can be muted\n");
-    write(fd, buffer, strlen(buffer));
-    for (size_t i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
-        snprintf(buffer, SIZE, " %02d", i);
-        mStreams[i].dump(buffer + 3, SIZE);
-        write(fd, buffer, strlen(buffer));
-    }
-
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-// AudioPolicyManagerBase
-// ----------------------------------------------------------------------------
-
-AudioPolicyManagerBase::AudioPolicyManagerBase(AudioPolicyClientInterface *clientInterface)
-    :
-#ifdef AUDIO_POLICY_TEST
-    Thread(false),
-#endif //AUDIO_POLICY_TEST
-    mPhoneState(AudioSystem::MODE_NORMAL), mRingerMode(0), mMusicStopTime(0), mLimitRingtoneVolume(false)
-{
-    mpClientInterface = clientInterface;
-
-    for (int i = 0; i < AudioSystem::NUM_FORCE_USE; i++) {
-        mForceUse[i] = AudioSystem::FORCE_NONE;
-    }
-
-    // devices available by default are speaker, ear piece and microphone
-    mAvailableOutputDevices = AudioSystem::DEVICE_OUT_EARPIECE |
-                        AudioSystem::DEVICE_OUT_SPEAKER;
-    mAvailableInputDevices = AudioSystem::DEVICE_IN_BUILTIN_MIC;
-
-#ifdef WITH_A2DP
-    mA2dpOutput = 0;
-    mDuplicatedOutput = 0;
-    mA2dpDeviceAddress = String8("");
-#endif
-    mScoDeviceAddress = String8("");
-
-    // open hardware output
-    AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
-    outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
-    mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
-                                    &outputDesc->mSamplingRate,
-                                    &outputDesc->mFormat,
-                                    &outputDesc->mChannels,
-                                    &outputDesc->mLatency,
-                                    outputDesc->mFlags);
-
-    if (mHardwareOutput == 0) {
-        LOGE("Failed to initialize hardware output stream, samplingRate: %d, format %d, channels %d",
-                outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
-    } else {
-        addOutput(mHardwareOutput, outputDesc);
-        setOutputDevice(mHardwareOutput, (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER, true);
-    }
-
-    updateDeviceForStrategy();
-#ifdef AUDIO_POLICY_TEST
-    AudioParameter outputCmd = AudioParameter();
-    outputCmd.addInt(String8("set_id"), 0);
-    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
-
-    mTestDevice = AudioSystem::DEVICE_OUT_SPEAKER;
-    mTestSamplingRate = 44100;
-    mTestFormat = AudioSystem::PCM_16_BIT;
-    mTestChannels =  AudioSystem::CHANNEL_OUT_STEREO;
-    mTestLatencyMs = 0;
-    mCurOutput = 0;
-    mDirectOutput = false;
-    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
-        mTestOutputs[i] = 0;
-    }
-
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    snprintf(buffer, SIZE, "AudioPolicyManagerTest");
-    run(buffer, ANDROID_PRIORITY_AUDIO);
-#endif //AUDIO_POLICY_TEST
-}
-
-AudioPolicyManagerBase::~AudioPolicyManagerBase()
-{
-#ifdef AUDIO_POLICY_TEST
-    exit();
-#endif //AUDIO_POLICY_TEST
-   for (size_t i = 0; i < mOutputs.size(); i++) {
-        mpClientInterface->closeOutput(mOutputs.keyAt(i));
-        delete mOutputs.valueAt(i);
-   }
-   mOutputs.clear();
-   for (size_t i = 0; i < mInputs.size(); i++) {
-        mpClientInterface->closeInput(mInputs.keyAt(i));
-        delete mInputs.valueAt(i);
-   }
-   mInputs.clear();
-}
-
-#ifdef AUDIO_POLICY_TEST
-bool AudioPolicyManagerBase::threadLoop()
-{
-    LOGV("entering threadLoop()");
-    while (!exitPending())
-    {
-        String8 command;
-        int valueInt;
-        String8 value;
-
-        Mutex::Autolock _l(mLock);
-        mWaitWorkCV.waitRelative(mLock, milliseconds(50));
-
-        command = mpClientInterface->getParameters(0, String8("test_cmd_policy"));
-        AudioParameter param = AudioParameter(command);
-
-        if (param.getInt(String8("test_cmd_policy"), valueInt) == NO_ERROR &&
-            valueInt != 0) {
-            LOGV("Test command %s received", command.string());
-            String8 target;
-            if (param.get(String8("target"), target) != NO_ERROR) {
-                target = "Manager";
-            }
-            if (param.getInt(String8("test_cmd_policy_output"), valueInt) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_output"));
-                mCurOutput = valueInt;
-            }
-            if (param.get(String8("test_cmd_policy_direct"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_direct"));
-                if (value == "false") {
-                    mDirectOutput = false;
-                } else if (value == "true") {
-                    mDirectOutput = true;
-                }
-            }
-            if (param.getInt(String8("test_cmd_policy_input"), valueInt) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_input"));
-                mTestInput = valueInt;
-            }
-
-            if (param.get(String8("test_cmd_policy_format"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_format"));
-                int format = AudioSystem::INVALID_FORMAT;
-                if (value == "PCM 16 bits") {
-                    format = AudioSystem::PCM_16_BIT;
-                } else if (value == "PCM 8 bits") {
-                    format = AudioSystem::PCM_8_BIT;
-                } else if (value == "Compressed MP3") {
-                    format = AudioSystem::MP3;
-                }
-                if (format != AudioSystem::INVALID_FORMAT) {
-                    if (target == "Manager") {
-                        mTestFormat = format;
-                    } else if (mTestOutputs[mCurOutput] != 0) {
-                        AudioParameter outputParam = AudioParameter();
-                        outputParam.addInt(String8("format"), format);
-                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
-                    }
-                }
-            }
-            if (param.get(String8("test_cmd_policy_channels"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_channels"));
-                int channels = 0;
-
-                if (value == "Channels Stereo") {
-                    channels =  AudioSystem::CHANNEL_OUT_STEREO;
-                } else if (value == "Channels Mono") {
-                    channels =  AudioSystem::CHANNEL_OUT_MONO;
-                }
-                if (channels != 0) {
-                    if (target == "Manager") {
-                        mTestChannels = channels;
-                    } else if (mTestOutputs[mCurOutput] != 0) {
-                        AudioParameter outputParam = AudioParameter();
-                        outputParam.addInt(String8("channels"), channels);
-                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
-                    }
-                }
-            }
-            if (param.getInt(String8("test_cmd_policy_sampleRate"), valueInt) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_sampleRate"));
-                if (valueInt >= 0 && valueInt <= 96000) {
-                    int samplingRate = valueInt;
-                    if (target == "Manager") {
-                        mTestSamplingRate = samplingRate;
-                    } else if (mTestOutputs[mCurOutput] != 0) {
-                        AudioParameter outputParam = AudioParameter();
-                        outputParam.addInt(String8("sampling_rate"), samplingRate);
-                        mpClientInterface->setParameters(mTestOutputs[mCurOutput], outputParam.toString());
-                    }
-                }
-            }
-
-            if (param.get(String8("test_cmd_policy_reopen"), value) == NO_ERROR) {
-                param.remove(String8("test_cmd_policy_reopen"));
-
-                mpClientInterface->closeOutput(mHardwareOutput);
-                delete mOutputs.valueFor(mHardwareOutput);
-                mOutputs.removeItem(mHardwareOutput);
-
-                AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
-                outputDesc->mDevice = (uint32_t)AudioSystem::DEVICE_OUT_SPEAKER;
-                mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
-                                                &outputDesc->mSamplingRate,
-                                                &outputDesc->mFormat,
-                                                &outputDesc->mChannels,
-                                                &outputDesc->mLatency,
-                                                outputDesc->mFlags);
-                if (mHardwareOutput == 0) {
-                    LOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
-                            outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannels);
-                } else {
-                    AudioParameter outputCmd = AudioParameter();
-                    outputCmd.addInt(String8("set_id"), 0);
-                    mpClientInterface->setParameters(mHardwareOutput, outputCmd.toString());
-                    addOutput(mHardwareOutput, outputDesc);
-                }
-            }
-
-
-            mpClientInterface->setParameters(0, String8("test_cmd_policy="));
-        }
-    }
-    return false;
-}
-
-void AudioPolicyManagerBase::exit()
-{
-    {
-        AutoMutex _l(mLock);
-        requestExit();
-        mWaitWorkCV.signal();
-    }
-    requestExitAndWait();
-}
-
-int AudioPolicyManagerBase::testOutputIndex(audio_io_handle_t output)
-{
-    for (int i = 0; i < NUM_TEST_OUTPUTS; i++) {
-        if (output == mTestOutputs[i]) return i;
-    }
-    return 0;
-}
-#endif //AUDIO_POLICY_TEST
-
-// ---
-
-void AudioPolicyManagerBase::addOutput(audio_io_handle_t id, AudioOutputDescriptor *outputDesc)
-{
-    outputDesc->mId = id;
-    mOutputs.add(id, outputDesc);
-}
-
-
-#ifdef WITH_A2DP
-status_t AudioPolicyManagerBase::handleA2dpConnection(AudioSystem::audio_devices device,
-                                                 const char *device_address)
-{
-    // when an A2DP device is connected, open an A2DP and a duplicated output
-    LOGV("opening A2DP output for device %s", device_address);
-    AudioOutputDescriptor *outputDesc = new AudioOutputDescriptor();
-    outputDesc->mDevice = device;
-    mA2dpOutput = mpClientInterface->openOutput(&outputDesc->mDevice,
-                                            &outputDesc->mSamplingRate,
-                                            &outputDesc->mFormat,
-                                            &outputDesc->mChannels,
-                                            &outputDesc->mLatency,
-                                            outputDesc->mFlags);
-    if (mA2dpOutput) {
-        // add A2DP output descriptor
-        addOutput(mA2dpOutput, outputDesc);
-        // set initial stream volume for A2DP device
-        applyStreamVolumes(mA2dpOutput, device);
-        if (a2dpUsedForSonification()) {
-            mDuplicatedOutput = mpClientInterface->openDuplicateOutput(mA2dpOutput, mHardwareOutput);
-        }
-        if (mDuplicatedOutput != 0 ||
-            !a2dpUsedForSonification()) {
-            // If both A2DP and duplicated outputs are open, send device address to A2DP hardware
-            // interface
-            AudioParameter param;
-            param.add(String8("a2dp_sink_address"), String8(device_address));
-            mpClientInterface->setParameters(mA2dpOutput, param.toString());
-            mA2dpDeviceAddress = String8(device_address, MAX_DEVICE_ADDRESS_LEN);
-
-            if (a2dpUsedForSonification()) {
-                // add duplicated output descriptor
-                AudioOutputDescriptor *dupOutputDesc = new AudioOutputDescriptor();
-                dupOutputDesc->mOutput1 = mOutputs.valueFor(mHardwareOutput);
-                dupOutputDesc->mOutput2 = mOutputs.valueFor(mA2dpOutput);
-                dupOutputDesc->mSamplingRate = outputDesc->mSamplingRate;
-                dupOutputDesc->mFormat = outputDesc->mFormat;
-                dupOutputDesc->mChannels = outputDesc->mChannels;
-                dupOutputDesc->mLatency = outputDesc->mLatency;
-                addOutput(mDuplicatedOutput, dupOutputDesc);
-                applyStreamVolumes(mDuplicatedOutput, device);
-            }
-        } else {
-            LOGW("getOutput() could not open duplicated output for %d and %d",
-                    mHardwareOutput, mA2dpOutput);
-            mpClientInterface->closeOutput(mA2dpOutput);
-            mOutputs.removeItem(mA2dpOutput);
-            mA2dpOutput = 0;
-            delete outputDesc;
-            return NO_INIT;
-        }
-    } else {
-        LOGW("setDeviceConnectionState() could not open A2DP output for device %x", device);
-        delete outputDesc;
-        return NO_INIT;
-    }
-    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
-
-    if (mScoDeviceAddress != "") {
-        // It is normal to suspend twice if we are both in call,
-        // and have the hardware audio output routed to BT SCO
-        if (mPhoneState != AudioSystem::MODE_NORMAL) {
-            mpClientInterface->suspendOutput(mA2dpOutput);
-        }
-        if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)hwOutputDesc->device())) {
-            mpClientInterface->suspendOutput(mA2dpOutput);
-        }
-    }
-
-    if (!a2dpUsedForSonification()) {
-        // mute music on A2DP output if a notification or ringtone is playing
-        uint32_t refCount = hwOutputDesc->strategyRefCount(STRATEGY_SONIFICATION);
-        for (uint32_t i = 0; i < refCount; i++) {
-            setStrategyMute(STRATEGY_MEDIA, true, mA2dpOutput);
-        }
-    }
-    return NO_ERROR;
-}
-
-status_t AudioPolicyManagerBase::handleA2dpDisconnection(AudioSystem::audio_devices device,
-                                                    const char *device_address)
-{
-    if (mA2dpOutput == 0) {
-        LOGW("setDeviceConnectionState() disconnecting A2DP and no A2DP output!");
-        return INVALID_OPERATION;
-    }
-
-    if (mA2dpDeviceAddress != device_address) {
-        LOGW("setDeviceConnectionState() disconnecting unknow A2DP sink address %s", device_address);
-        return INVALID_OPERATION;
-    }
-
-    // mute media strategy to avoid outputting sound on hardware output while music stream
-    // is switched from A2DP output and before music is paused by music application
-    setStrategyMute(STRATEGY_MEDIA, true, mHardwareOutput);
-    setStrategyMute(STRATEGY_MEDIA, false, mHardwareOutput, MUTE_TIME_MS);
-
-    if (!a2dpUsedForSonification()) {
-        // unmute music on A2DP output if a notification or ringtone is playing
-        uint32_t refCount = mOutputs.valueFor(mHardwareOutput)->strategyRefCount(STRATEGY_SONIFICATION);
-        for (uint32_t i = 0; i < refCount; i++) {
-            setStrategyMute(STRATEGY_MEDIA, false, mA2dpOutput);
-        }
-    }
-    mA2dpDeviceAddress = "";
-    return NO_ERROR;
-}
-
-void AudioPolicyManagerBase::closeA2dpOutputs()
-{
-    LOGV("setDeviceConnectionState() closing A2DP and duplicated output!");
-
-    if (mDuplicatedOutput != 0) {
-        mpClientInterface->closeOutput(mDuplicatedOutput);
-        delete mOutputs.valueFor(mDuplicatedOutput);
-        mOutputs.removeItem(mDuplicatedOutput);
-        mDuplicatedOutput = 0;
-    }
-    if (mA2dpOutput != 0) {
-        AudioParameter param;
-        param.add(String8("closing"), String8("true"));
-        mpClientInterface->setParameters(mA2dpOutput, param.toString());
-        mpClientInterface->closeOutput(mA2dpOutput);
-        delete mOutputs.valueFor(mA2dpOutput);
-        mOutputs.removeItem(mA2dpOutput);
-        mA2dpOutput = 0;
-    }
-}
-
-void AudioPolicyManagerBase::checkOutputForStrategy(routing_strategy strategy, uint32_t &newDevice)
-{
-    uint32_t prevDevice = getDeviceForStrategy(strategy);
-    uint32_t curDevice = getDeviceForStrategy(strategy, false);
-    bool a2dpWasUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(prevDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
-    bool a2dpIsUsed = AudioSystem::isA2dpDevice((AudioSystem::audio_devices)(curDevice & ~AudioSystem::DEVICE_OUT_SPEAKER));
-    AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mHardwareOutput);
-    AudioOutputDescriptor *a2dpOutputDesc;
-
-    if (a2dpWasUsed && !a2dpIsUsed) {
-        bool dupUsed = a2dpUsedForSonification() && a2dpWasUsed && (AudioSystem::popCount(prevDevice) == 2);
-
-        if (dupUsed) {
-            LOGV("checkOutputForStrategy() moving strategy %d to duplicated", strategy);
-            a2dpOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
-        } else {
-            LOGV("checkOutputForStrategy() moving strategy %d to a2dp", strategy);
-            a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
-        }
-
-        for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
-            if (getStrategy((AudioSystem::stream_type)i) == strategy) {
-                mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, mHardwareOutput);
-                int refCount = a2dpOutputDesc->mRefCount[i];
-                // in the case of duplicated output, the ref count is first incremented
-                // and then decremented on hardware output tus keeping its value
-                hwOutputDesc->changeRefCount((AudioSystem::stream_type)i, refCount);
-                a2dpOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
-            }
-        }
-        // do not change newDevice if it was already set before this call by a previous call to
-        // getNewDevice() or checkOutputForStrategy() for a strategy with higher priority
-        if (newDevice == 0 && hwOutputDesc->isUsedByStrategy(strategy)) {
-            newDevice = getDeviceForStrategy(strategy, false);
-        }
-    }
-    if (a2dpIsUsed && !a2dpWasUsed) {
-        bool dupUsed = a2dpUsedForSonification() && a2dpIsUsed && (AudioSystem::popCount(curDevice) == 2);
-        audio_io_handle_t a2dpOutput;
-
-        if (dupUsed) {
-            LOGV("checkOutputForStrategy() moving strategy %d from duplicated", strategy);
-            a2dpOutputDesc = mOutputs.valueFor(mDuplicatedOutput);
-            a2dpOutput = mDuplicatedOutput;
-        } else {
-            LOGV("checkOutputForStrategy() moving strategy %d from a2dp", strategy);
-            a2dpOutputDesc = mOutputs.valueFor(mA2dpOutput);
-            a2dpOutput = mA2dpOutput;
-        }
-
-        for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
-            if (getStrategy((AudioSystem::stream_type)i) == strategy) {
-                mpClientInterface->setStreamOutput((AudioSystem::stream_type)i, a2dpOutput);
-                int refCount = hwOutputDesc->mRefCount[i];
-                // in the case of duplicated output, the ref count is first incremented
-                // and then decremented on hardware output tus keeping its value
-                a2dpOutputDesc->changeRefCount((AudioSystem::stream_type)i, refCount);
-                hwOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
-            }
-        }
-    }
-}
-
-void AudioPolicyManagerBase::checkOutputForAllStrategies(uint32_t &newDevice)
-{
-    // Check strategies in order of priority so that once newDevice is set
-    // for a given strategy it is not modified by subsequent calls to
-    // checkOutputForStrategy()
-    checkOutputForStrategy(STRATEGY_PHONE, newDevice);
-    checkOutputForStrategy(STRATEGY_SONIFICATION, newDevice);
-    checkOutputForStrategy(STRATEGY_MEDIA, newDevice);
-    checkOutputForStrategy(STRATEGY_DTMF, newDevice);
-}
-
-#endif
-
-uint32_t AudioPolicyManagerBase::getNewDevice(audio_io_handle_t output, bool fromCache)
-{
-    uint32_t device = 0;
-
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    // check the following by order of priority to request a routing change if necessary:
-    // 1: we are in call or the strategy phone is active on the hardware output:
-    //      use device for strategy phone
-    // 2: the strategy sonification is active on the hardware output:
-    //      use device for strategy sonification
-    // 3: the strategy media is active on the hardware output:
-    //      use device for strategy media
-    // 4: the strategy DTMF is active on the hardware output:
-    //      use device for strategy DTMF
-    if (mPhoneState == AudioSystem::MODE_IN_CALL ||
-        outputDesc->isUsedByStrategy(STRATEGY_PHONE)) {
-        device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
-    } else if (outputDesc->isUsedByStrategy(STRATEGY_SONIFICATION)) {
-        device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
-    } else if (outputDesc->isUsedByStrategy(STRATEGY_MEDIA)) {
-        device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
-    } else if (outputDesc->isUsedByStrategy(STRATEGY_DTMF)) {
-        device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
-    }
-
-    LOGV("getNewDevice() selected device %x", device);
-    return device;
-}
-
-AudioPolicyManagerBase::routing_strategy AudioPolicyManagerBase::getStrategy(AudioSystem::stream_type stream)
-{
-    // stream to strategy mapping
-    switch (stream) {
-    case AudioSystem::VOICE_CALL:
-    case AudioSystem::BLUETOOTH_SCO:
-        return STRATEGY_PHONE;
-    case AudioSystem::RING:
-    case AudioSystem::NOTIFICATION:
-    case AudioSystem::ALARM:
-    case AudioSystem::ENFORCED_AUDIBLE:
-        return STRATEGY_SONIFICATION;
-    case AudioSystem::DTMF:
-        return STRATEGY_DTMF;
-    default:
-        LOGE("unknown stream type");
-    case AudioSystem::SYSTEM:
-        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
-        // while key clicks are played produces a poor result
-    case AudioSystem::TTS:
-    case AudioSystem::MUSIC:
-        return STRATEGY_MEDIA;
-    }
-}
-
-uint32_t AudioPolicyManagerBase::getDeviceForStrategy(routing_strategy strategy, bool fromCache)
-{
-    uint32_t device = 0;
-
-    if (fromCache) {
-        LOGV("getDeviceForStrategy() from cache strategy %d, device %x", strategy, mDeviceForStrategy[strategy]);
-        return mDeviceForStrategy[strategy];
-    }
-
-    switch (strategy) {
-    case STRATEGY_DTMF:
-        if (mPhoneState != AudioSystem::MODE_IN_CALL) {
-            // when off call, DTMF strategy follows the same rules as MEDIA strategy
-            device = getDeviceForStrategy(STRATEGY_MEDIA, false);
-            break;
-        }
-        // when in call, DTMF and PHONE strategies follow the same rules
-        // FALL THROUGH
-
-    case STRATEGY_PHONE:
-        // for phone strategy, we first consider the forced use and then the available devices by order
-        // of priority
-        switch (mForceUse[AudioSystem::FOR_COMMUNICATION]) {
-        case AudioSystem::FORCE_BT_SCO:
-            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
-                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
-                if (device) break;
-            }
-            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
-            if (device) break;
-            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO;
-            if (device) break;
-            // if SCO device is requested but no SCO device is available, fall back to default case
-            // FALL THROUGH
-
-        default:    // FORCE_NONE
-            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
-            if (device) break;
-            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
-            if (device) break;
-#ifdef WITH_A2DP
-            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
-            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
-                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
-                if (device) break;
-                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
-                if (device) break;
-            }
-#endif
-            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_EARPIECE;
-            if (device == 0) {
-                LOGE("getDeviceForStrategy() earpiece device not found");
-            }
-            break;
-
-        case AudioSystem::FORCE_SPEAKER:
-            if (mPhoneState != AudioSystem::MODE_IN_CALL || strategy != STRATEGY_DTMF) {
-                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
-                if (device) break;
-            }
-#ifdef WITH_A2DP
-            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
-            // A2DP speaker when forcing to speaker output
-            if (mPhoneState != AudioSystem::MODE_IN_CALL) {
-                device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
-                if (device) break;
-            }
-#endif
-            device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
-            if (device == 0) {
-                LOGE("getDeviceForStrategy() speaker device not found");
-            }
-            break;
-        }
-    break;
-
-    case STRATEGY_SONIFICATION:
-
-        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
-        // handleIncallSonification().
-        if (mPhoneState == AudioSystem::MODE_IN_CALL) {
-            device = getDeviceForStrategy(STRATEGY_PHONE, false);
-            break;
-        }
-        device = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
-        if (device == 0) {
-            LOGE("getDeviceForStrategy() speaker device not found");
-        }
-        // The second device used for sonification is the same as the device used by media strategy
-        // FALL THROUGH
-
-    case STRATEGY_MEDIA: {
-        uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
-        if (device2 == 0) {
-            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
-        }
-        if (device2 == 0) {
-            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
-        }
-#ifdef WITH_A2DP
-        if (mA2dpOutput != 0) {
-            if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
-                break;
-            }
-            if (device2 == 0) {
-                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP;
-            }
-            if (device2 == 0) {
-                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
-            }
-            if (device2 == 0) {
-                device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
-            }
-        }
-#endif
-        if (device2 == 0) {
-            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
-        }
-
-        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION, 0 otherwise
-        device |= device2;
-        if (device == 0) {
-            LOGE("getDeviceForStrategy() speaker device not found");
-        }
-        } break;
-
-    default:
-        LOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
-        break;
-    }
-
-    LOGV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
-    return device;
-}
-
-void AudioPolicyManagerBase::updateDeviceForStrategy()
-{
-    for (int i = 0; i < NUM_STRATEGIES; i++) {
-        mDeviceForStrategy[i] = getDeviceForStrategy((routing_strategy)i, false);
-    }
-}
-
-void AudioPolicyManagerBase::setOutputDevice(audio_io_handle_t output, uint32_t device, bool force, int delayMs)
-{
-    LOGV("setOutputDevice() output %d device %x delayMs %d", output, device, delayMs);
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-
-
-    if (outputDesc->isDuplicated()) {
-        setOutputDevice(outputDesc->mOutput1->mId, device, force, delayMs);
-        setOutputDevice(outputDesc->mOutput2->mId, device, force, delayMs);
-        return;
-    }
-#ifdef WITH_A2DP
-    // filter devices according to output selected
-    if (output == mA2dpOutput) {
-        device &= AudioSystem::DEVICE_OUT_ALL_A2DP;
-    } else {
-        device &= ~AudioSystem::DEVICE_OUT_ALL_A2DP;
-    }
-#endif
-
-    uint32_t prevDevice = (uint32_t)outputDesc->device();
-    // Do not change the routing if:
-    //  - the requestede device is 0
-    //  - the requested device is the same as current device and force is not specified.
-    // Doing this check here allows the caller to call setOutputDevice() without conditions
-    if ((device == 0 || device == prevDevice) && !force) {
-        LOGV("setOutputDevice() setting same device %x or null device for output %d", device, output);
-        return;
-    }
-
-    outputDesc->mDevice = device;
-    // mute media streams if both speaker and headset are selected
-    if (output == mHardwareOutput && AudioSystem::popCount(device) == 2) {
-        setStrategyMute(STRATEGY_MEDIA, true, output);
-        // wait for the PCM output buffers to empty before proceeding with the rest of the command
-        usleep(outputDesc->mLatency*2*1000);
-    }
-#ifdef WITH_A2DP
-    // suspend A2DP output if SCO device is selected
-    if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)device)) {
-         if (mA2dpOutput != 0) {
-             mpClientInterface->suspendOutput(mA2dpOutput);
-         }
-    }
-#endif
-    // do the routing
-    AudioParameter param = AudioParameter();
-    param.addInt(String8(AudioParameter::keyRouting), (int)device);
-    mpClientInterface->setParameters(mHardwareOutput, param.toString(), delayMs);
-    // update stream volumes according to new device
-    applyStreamVolumes(output, device, delayMs);
-
-#ifdef WITH_A2DP
-    // if disconnecting SCO device, restore A2DP output
-    if (AudioSystem::isBluetoothScoDevice((AudioSystem::audio_devices)prevDevice)) {
-         if (mA2dpOutput != 0) {
-             LOGV("restore A2DP output");
-             mpClientInterface->restoreOutput(mA2dpOutput);
-         }
-    }
-#endif
-    // if changing from a combined headset + speaker route, unmute media streams
-    if (output == mHardwareOutput && AudioSystem::popCount(prevDevice) == 2) {
-        setStrategyMute(STRATEGY_MEDIA, false, output, delayMs);
-    }
-}
-
-uint32_t AudioPolicyManagerBase::getDeviceForInputSource(int inputSource)
-{
-    uint32_t device;
-
-    switch(inputSource) {
-    case AUDIO_SOURCE_DEFAULT:
-    case AUDIO_SOURCE_MIC:
-    case AUDIO_SOURCE_VOICE_RECOGNITION:
-        if (mForceUse[AudioSystem::FOR_RECORD] == AudioSystem::FORCE_BT_SCO &&
-            mAvailableInputDevices & AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
-            device = AudioSystem::DEVICE_IN_BLUETOOTH_SCO_HEADSET;
-        } else if (mAvailableInputDevices & AudioSystem::DEVICE_IN_WIRED_HEADSET) {
-            device = AudioSystem::DEVICE_IN_WIRED_HEADSET;
-        } else {
-            device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
-        }
-        break;
-    case AUDIO_SOURCE_CAMCORDER:
-        if (hasBackMicrophone()) {
-            device = AudioSystem::DEVICE_IN_BACK_MIC;
-        } else {
-            device = AudioSystem::DEVICE_IN_BUILTIN_MIC;
-        }
-        break;
-    case AUDIO_SOURCE_VOICE_UPLINK:
-    case AUDIO_SOURCE_VOICE_DOWNLINK:
-    case AUDIO_SOURCE_VOICE_CALL:
-        device = AudioSystem::DEVICE_IN_VOICE_CALL;
-        break;
-    default:
-        LOGW("getInput() invalid input source %d", inputSource);
-        device = 0;
-        break;
-    }
-    LOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
-    return device;
-}
-
-audio_io_handle_t AudioPolicyManagerBase::getActiveInput()
-{
-    for (size_t i = 0; i < mInputs.size(); i++) {
-        if (mInputs.valueAt(i)->mRefCount > 0) {
-            return mInputs.keyAt(i);
-        }
-    }
-    return 0;
-}
-
-float AudioPolicyManagerBase::computeVolume(int stream, int index, audio_io_handle_t output, uint32_t device)
-{
-    float volume = 1.0;
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-    StreamDescriptor &streamDesc = mStreams[stream];
-
-    if (device == 0) {
-        device = outputDesc->device();
-    }
-
-    int volInt = (100 * (index - streamDesc.mIndexMin)) / (streamDesc.mIndexMax - streamDesc.mIndexMin);
-    volume = AudioSystem::linearToLog(volInt);
-
-    // if a headset is connected, apply the following rules to ring tones and notifications
-    // to avoid sound level bursts in user's ears:
-    // - always attenuate ring tones and notifications volume by 6dB
-    // - if music is playing, always limit the volume to current music volume,
-    // with a minimum threshold at -36dB so that notification is always perceived.
-    if ((device &
-        (AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP |
-        AudioSystem::DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES |
-        AudioSystem::DEVICE_OUT_WIRED_HEADSET |
-        AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)) &&
-        (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) &&
-        streamDesc.mCanBeMuted) {
-        volume *= SONIFICATION_HEADSET_VOLUME_FACTOR;
-        // when the phone is ringing we must consider that music could have been paused just before
-        // by the music application and behave as if music was active if the last music track was
-        // just stopped
-        if (outputDesc->mRefCount[AudioSystem::MUSIC] || mLimitRingtoneVolume) {
-            float musicVol = computeVolume(AudioSystem::MUSIC, mStreams[AudioSystem::MUSIC].mIndexCur, output, device);
-            float minVol = (musicVol > SONIFICATION_HEADSET_VOLUME_MIN) ? musicVol : SONIFICATION_HEADSET_VOLUME_MIN;
-            if (volume > minVol) {
-                volume = minVol;
-                LOGV("computeVolume limiting volume to %f musicVol %f", minVol, musicVol);
-            }
-        }
-    }
-
-    return volume;
-}
-
-status_t AudioPolicyManagerBase::checkAndSetVolume(int stream, int index, audio_io_handle_t output, uint32_t device, int delayMs, bool force)
-{
-
-    // do not change actual stream volume if the stream is muted
-    if (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {
-        LOGV("checkAndSetVolume() stream %d muted count %d", stream, mOutputs.valueFor(output)->mMuteCount[stream]);
-        return NO_ERROR;
-    }
-
-    // do not change in call volume if bluetooth is connected and vice versa
-    if ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||
-        (stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {
-        LOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
-             stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);
-        return INVALID_OPERATION;
-    }
-
-    float volume = computeVolume(stream, index, output, device);
-    // do not set volume if the float value did not change
-    if (volume != mOutputs.valueFor(output)->mCurVolume[stream] || force) {
-        mOutputs.valueFor(output)->mCurVolume[stream] = volume;
-        LOGV("setStreamVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);
-        if (stream == AudioSystem::VOICE_CALL ||
-            stream == AudioSystem::DTMF ||
-            stream == AudioSystem::BLUETOOTH_SCO) {
-            float voiceVolume = -1.0;
-            // offset value to reflect actual hardware volume that never reaches 0
-            // 1% corresponds roughly to first step in VOICE_CALL stream volume setting (see AudioService.java)
-            volume = 0.01 + 0.99 * volume;
-            if (stream == AudioSystem::VOICE_CALL) {
-                voiceVolume = (float)index/(float)mStreams[stream].mIndexMax;
-            } else if (stream == AudioSystem::BLUETOOTH_SCO) {
-                voiceVolume = 1.0;
-            }
-            if (voiceVolume >= 0 && output == mHardwareOutput) {
-                mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
-            }
-        }
-        mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);
-    }
-
-    return NO_ERROR;
-}
-
-void AudioPolicyManagerBase::applyStreamVolumes(audio_io_handle_t output, uint32_t device, int delayMs)
-{
-    LOGV("applyStreamVolumes() for output %d and device %x", output, device);
-
-    for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
-        checkAndSetVolume(stream, mStreams[stream].mIndexCur, output, device, delayMs);
-    }
-}
-
-void AudioPolicyManagerBase::setStrategyMute(routing_strategy strategy, bool on, audio_io_handle_t output, int delayMs)
-{
-    LOGV("setStrategyMute() strategy %d, mute %d, output %d", strategy, on, output);
-    for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
-        if (getStrategy((AudioSystem::stream_type)stream) == strategy) {
-            setStreamMute(stream, on, output, delayMs);
-        }
-    }
-}
-
-void AudioPolicyManagerBase::setStreamMute(int stream, bool on, audio_io_handle_t output, int delayMs)
-{
-    StreamDescriptor &streamDesc = mStreams[stream];
-    AudioOutputDescriptor *outputDesc = mOutputs.valueFor(output);
-
-    LOGV("setStreamMute() stream %d, mute %d, output %d, mMuteCount %d", stream, on, output, outputDesc->mMuteCount[stream]);
-
-    if (on) {
-        if (outputDesc->mMuteCount[stream] == 0) {
-            if (streamDesc.mCanBeMuted) {
-                checkAndSetVolume(stream, 0, output, outputDesc->device(), delayMs);
-            }
-        }
-        // increment mMuteCount after calling checkAndSetVolume() so that volume change is not ignored
-        outputDesc->mMuteCount[stream]++;
-    } else {
-        if (outputDesc->mMuteCount[stream] == 0) {
-            LOGW("setStreamMute() unmuting non muted stream!");
-            return;
-        }
-        if (--outputDesc->mMuteCount[stream] == 0) {
-            checkAndSetVolume(stream, streamDesc.mIndexCur, output, outputDesc->device(), delayMs);
-        }
-    }
-}
-
-void AudioPolicyManagerBase::handleIncallSonification(int stream, bool starting, bool stateChange)
-{
-    // if the stream pertains to sonification strategy and we are in call we must
-    // mute the stream if it is low visibility. If it is high visibility, we must play a tone
-    // in the device used for phone strategy and play the tone if the selected device does not
-    // interfere with the device used for phone strategy
-    // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
-    // many times as there are active tracks on the output
-
-    if (getStrategy((AudioSystem::stream_type)stream) == STRATEGY_SONIFICATION) {
-        AudioOutputDescriptor *outputDesc = mOutputs.valueFor(mHardwareOutput);
-        LOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
-                stream, starting, outputDesc->mDevice, stateChange);
-        if (outputDesc->mRefCount[stream]) {
-            int muteCount = 1;
-            if (stateChange) {
-                muteCount = outputDesc->mRefCount[stream];
-            }
-            if (AudioSystem::isLowVisibility((AudioSystem::stream_type)stream)) {
-                LOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
-                for (int i = 0; i < muteCount; i++) {
-                    setStreamMute(stream, starting, mHardwareOutput);
-                }
-            } else {
-                LOGV("handleIncallSonification() high visibility");
-                if (outputDesc->device() & getDeviceForStrategy(STRATEGY_PHONE)) {
-                    LOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
-                    for (int i = 0; i < muteCount; i++) {
-                        setStreamMute(stream, starting, mHardwareOutput);
-                    }
-                }
-                if (starting) {
-                    mpClientInterface->startTone(ToneGenerator::TONE_SUP_CALL_WAITING, AudioSystem::VOICE_CALL);
-                } else {
-                    mpClientInterface->stopTone();
-                }
-            }
-        }
-    }
-}
-
-bool AudioPolicyManagerBase::needsDirectOuput(AudioSystem::stream_type stream,
-                                    uint32_t samplingRate,
-                                    uint32_t format,
-                                    uint32_t channels,
-                                    AudioSystem::output_flags flags,
-                                    uint32_t device)
-{
-   return ((flags & AudioSystem::OUTPUT_FLAG_DIRECT) ||
-          (format !=0 && !AudioSystem::isLinearPCM(format)));
-}
-
-// --- AudioOutputDescriptor class implementation
-
-AudioPolicyManagerBase::AudioOutputDescriptor::AudioOutputDescriptor()
-    : mId(0), mSamplingRate(0), mFormat(0), mChannels(0), mLatency(0),
-    mFlags((AudioSystem::output_flags)0), mDevice(0), mOutput1(0), mOutput2(0)
-{
-    // clear usage count for all stream types
-    for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
-        mRefCount[i] = 0;
-        mCurVolume[i] = -1.0;
-        mMuteCount[i] = 0;
-    }
-}
-
-uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::device()
-{
-    uint32_t device = 0;
-    if (isDuplicated()) {
-        device = mOutput1->mDevice | mOutput2->mDevice;
-    } else {
-        device = mDevice;
-    }
-    return device;
-}
-
-void AudioPolicyManagerBase::AudioOutputDescriptor::changeRefCount(AudioSystem::stream_type stream, int delta)
-{
-    // forward usage count change to attached outputs
-    if (isDuplicated()) {
-        mOutput1->changeRefCount(stream, delta);
-        mOutput2->changeRefCount(stream, delta);
-    }
-    if ((delta + (int)mRefCount[stream]) < 0) {
-        LOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", delta, stream, mRefCount[stream]);
-        mRefCount[stream] = 0;
-        return;
-    }
-    mRefCount[stream] += delta;
-    LOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
-}
-
-uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::refCount()
-{
-    uint32_t refcount = 0;
-    for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
-        refcount += mRefCount[i];
-    }
-    return refcount;
-}
-
-uint32_t AudioPolicyManagerBase::AudioOutputDescriptor::strategyRefCount(routing_strategy strategy)
-{
-    uint32_t refCount = 0;
-    for (int i = 0; i < (int)AudioSystem::NUM_STREAM_TYPES; i++) {
-        if (getStrategy((AudioSystem::stream_type)i) == strategy) {
-            refCount += mRefCount[i];
-        }
-    }
-    return refCount;
-}
-
-
-status_t AudioPolicyManagerBase::AudioOutputDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", device());
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
-    result.append(buffer);
-    for (int i = 0; i < AudioSystem::NUM_STREAM_TYPES; i++) {
-        snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n", i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
-        result.append(buffer);
-    }
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- AudioInputDescriptor class implementation
-
-AudioPolicyManagerBase::AudioInputDescriptor::AudioInputDescriptor()
-    : mSamplingRate(0), mFormat(0), mChannels(0),
-     mAcoustics((AudioSystem::audio_in_acoustics)0), mDevice(0), mRefCount(0)
-{
-}
-
-status_t AudioPolicyManagerBase::AudioInputDescriptor::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Format: %d\n", mFormat);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Channels: %08x\n", mChannels);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Acoustics %08x\n", mAcoustics);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
-    result.append(buffer);
-    snprintf(buffer, SIZE, " Ref Count %d\n", mRefCount);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    return NO_ERROR;
-}
-
-// --- StreamDescriptor class implementation
-
-void AudioPolicyManagerBase::StreamDescriptor::dump(char* buffer, size_t size)
-{
-    snprintf(buffer, size, "      %02d         %02d         %02d         %d\n",
-            mIndexMin,
-            mIndexMax,
-            mIndexCur,
-            mCanBeMuted);
-}
-
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioPolicyService.cpp b/libs/audioflinger/AudioPolicyService.cpp
deleted file mode 100644
index bb3905c..0000000
--- a/libs/audioflinger/AudioPolicyService.cpp
+++ /dev/null
@@ -1,924 +0,0 @@
-/*
- * Copyright (C) 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.
- */
-
-#define LOG_TAG "AudioPolicyService"
-//#define LOG_NDEBUG 0
-
-#undef __STRICT_ANSI__
-#define __STDINT_LIMITS
-#define __STDC_LIMIT_MACROS
-#include <stdint.h>
-
-#include <sys/time.h>
-#include <binder/IServiceManager.h>
-#include <utils/Log.h>
-#include <cutils/properties.h>
-#include <binder/IPCThreadState.h>
-#include <utils/String16.h>
-#include <utils/threads.h>
-#include "AudioPolicyService.h"
-#include <hardware_legacy/AudioPolicyManagerBase.h>
-#include <cutils/properties.h>
-#include <dlfcn.h>
-#include <hardware_legacy/power.h>
-
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
-
-namespace android {
-
-
-static const char *kDeadlockedString = "AudioPolicyService may be deadlocked\n";
-static const char *kCmdDeadlockedString = "AudioPolicyService command thread may be deadlocked\n";
-
-static const int kDumpLockRetries = 50;
-static const int kDumpLockSleep = 20000;
-
-static bool checkPermission() {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
-    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
-    bool ok = checkCallingPermission(String16("android.permission.MODIFY_AUDIO_SETTINGS"));
-    if (!ok) LOGE("Request requires android.permission.MODIFY_AUDIO_SETTINGS");
-    return ok;
-}
-
-// ----------------------------------------------------------------------------
-
-AudioPolicyService::AudioPolicyService()
-    : BnAudioPolicyService() , mpPolicyManager(NULL)
-{
-    char value[PROPERTY_VALUE_MAX];
-
-    // start tone playback thread
-    mTonePlaybackThread = new AudioCommandThread(String8(""));
-    // start audio commands thread
-    mAudioCommandThread = new AudioCommandThread(String8("ApmCommandThread"));
-
-#if (defined GENERIC_AUDIO) || (defined AUDIO_POLICY_TEST)
-    mpPolicyManager = new AudioPolicyManagerBase(this);
-    LOGV("build for GENERIC_AUDIO - using generic audio policy");
-#else
-    // if running in emulation - use the emulator driver
-    if (property_get("ro.kernel.qemu", value, 0)) {
-        LOGV("Running in emulation - using generic audio policy");
-        mpPolicyManager = new AudioPolicyManagerBase(this);
-    }
-    else {
-        LOGV("Using hardware specific audio policy");
-        mpPolicyManager = createAudioPolicyManager(this);
-    }
-#endif
-
-    // load properties
-    property_get("ro.camera.sound.forced", value, "0");
-    mpPolicyManager->setSystemProperty("ro.camera.sound.forced", value);
-}
-
-AudioPolicyService::~AudioPolicyService()
-{
-    mTonePlaybackThread->exit();
-    mTonePlaybackThread.clear();
-    mAudioCommandThread->exit();
-    mAudioCommandThread.clear();
-
-    if (mpPolicyManager) {
-        delete mpPolicyManager;
-    }
-}
-
-
-status_t AudioPolicyService::setDeviceConnectionState(AudioSystem::audio_devices device,
-                                                  AudioSystem::device_connection_state state,
-                                                  const char *device_address)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-    if (!AudioSystem::isOutputDevice(device) && !AudioSystem::isInputDevice(device)) {
-        return BAD_VALUE;
-    }
-    if (state != AudioSystem::DEVICE_STATE_AVAILABLE && state != AudioSystem::DEVICE_STATE_UNAVAILABLE) {
-        return BAD_VALUE;
-    }
-
-    LOGV("setDeviceConnectionState() tid %d", gettid());
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->setDeviceConnectionState(device, state, device_address);
-}
-
-AudioSystem::device_connection_state AudioPolicyService::getDeviceConnectionState(AudioSystem::audio_devices device,
-                                                  const char *device_address)
-{
-    if (mpPolicyManager == NULL) {
-        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
-    }
-    if (!checkPermission()) {
-        return AudioSystem::DEVICE_STATE_UNAVAILABLE;
-    }
-    return mpPolicyManager->getDeviceConnectionState(device, device_address);
-}
-
-status_t AudioPolicyService::setPhoneState(int state)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-    if (state < 0 || state >= AudioSystem::NUM_MODES) {
-        return BAD_VALUE;
-    }
-
-    LOGV("setPhoneState() tid %d", gettid());
-
-    // TODO: check if it is more appropriate to do it in platform specific policy manager
-    AudioSystem::setMode(state);
-
-    Mutex::Autolock _l(mLock);
-    mpPolicyManager->setPhoneState(state);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::setRingerMode(uint32_t mode, uint32_t mask)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-
-    mpPolicyManager->setRingerMode(mode, mask);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
-        return BAD_VALUE;
-    }
-    if (config < 0 || config >= AudioSystem::NUM_FORCE_CONFIG) {
-        return BAD_VALUE;
-    }
-    LOGV("setForceUse() tid %d", gettid());
-    Mutex::Autolock _l(mLock);
-    mpPolicyManager->setForceUse(usage, config);
-    return NO_ERROR;
-}
-
-AudioSystem::forced_config AudioPolicyService::getForceUse(AudioSystem::force_use usage)
-{
-    if (mpPolicyManager == NULL) {
-        return AudioSystem::FORCE_NONE;
-    }
-    if (!checkPermission()) {
-        return AudioSystem::FORCE_NONE;
-    }
-    if (usage < 0 || usage >= AudioSystem::NUM_FORCE_USE) {
-        return AudioSystem::FORCE_NONE;
-    }
-    return mpPolicyManager->getForceUse(usage);
-}
-
-audio_io_handle_t AudioPolicyService::getOutput(AudioSystem::stream_type stream,
-                                    uint32_t samplingRate,
-                                    uint32_t format,
-                                    uint32_t channels,
-                                    AudioSystem::output_flags flags)
-{
-    if (mpPolicyManager == NULL) {
-        return 0;
-    }
-    LOGV("getOutput() tid %d", gettid());
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->getOutput(stream, samplingRate, format, channels, flags);
-}
-
-status_t AudioPolicyService::startOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    LOGV("startOutput() tid %d", gettid());
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->startOutput(output, stream);
-}
-
-status_t AudioPolicyService::stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    LOGV("stopOutput() tid %d", gettid());
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->stopOutput(output, stream);
-}
-
-void AudioPolicyService::releaseOutput(audio_io_handle_t output)
-{
-    if (mpPolicyManager == NULL) {
-        return;
-    }
-    LOGV("releaseOutput() tid %d", gettid());
-    Mutex::Autolock _l(mLock);
-    mpPolicyManager->releaseOutput(output);
-}
-
-audio_io_handle_t AudioPolicyService::getInput(int inputSource,
-                                    uint32_t samplingRate,
-                                    uint32_t format,
-                                    uint32_t channels,
-                                    AudioSystem::audio_in_acoustics acoustics)
-{
-    if (mpPolicyManager == NULL) {
-        return 0;
-    }
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->getInput(inputSource, samplingRate, format, channels, acoustics);
-}
-
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->startInput(input);
-}
-
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    Mutex::Autolock _l(mLock);
-    return mpPolicyManager->stopInput(input);
-}
-
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
-{
-    if (mpPolicyManager == NULL) {
-        return;
-    }
-    Mutex::Autolock _l(mLock);
-    mpPolicyManager->releaseInput(input);
-}
-
-status_t AudioPolicyService::initStreamVolume(AudioSystem::stream_type stream,
-                                            int indexMin,
-                                            int indexMax)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
-        return BAD_VALUE;
-    }
-    mpPolicyManager->initStreamVolume(stream, indexMin, indexMax);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::setStreamVolumeIndex(AudioSystem::stream_type stream, int index)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
-        return BAD_VALUE;
-    }
-
-    return mpPolicyManager->setStreamVolumeIndex(stream, index);
-}
-
-status_t AudioPolicyService::getStreamVolumeIndex(AudioSystem::stream_type stream, int *index)
-{
-    if (mpPolicyManager == NULL) {
-        return NO_INIT;
-    }
-    if (!checkPermission()) {
-        return PERMISSION_DENIED;
-    }
-    if (stream < 0 || stream >= AudioSystem::NUM_STREAM_TYPES) {
-        return BAD_VALUE;
-    }
-    return mpPolicyManager->getStreamVolumeIndex(stream, index);
-}
-
-void AudioPolicyService::binderDied(const wp<IBinder>& who) {
-    LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(), IPCThreadState::self()->getCallingPid());
-}
-
-static bool tryLock(Mutex& mutex)
-{
-    bool locked = false;
-    for (int i = 0; i < kDumpLockRetries; ++i) {
-        if (mutex.tryLock() == NO_ERROR) {
-            locked = true;
-            break;
-        }
-        usleep(kDumpLockSleep);
-    }
-    return locked;
-}
-
-status_t AudioPolicyService::dumpInternals(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "PolicyManager Interface: %p\n", mpPolicyManager);
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Command Thread: %p\n", mAudioCommandThread.get());
-    result.append(buffer);
-    snprintf(buffer, SIZE, "Tones Thread: %p\n", mTonePlaybackThread.get());
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::dump(int fd, const Vector<String16>& args)
-{
-    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
-        dumpPermissionDenial(fd);
-    } else {
-        bool locked = tryLock(mLock);
-        if (!locked) {
-            String8 result(kDeadlockedString);
-            write(fd, result.string(), result.size());
-        }
-
-        dumpInternals(fd);
-        if (mAudioCommandThread != NULL) {
-            mAudioCommandThread->dump(fd);
-        }
-        if (mTonePlaybackThread != NULL) {
-            mTonePlaybackThread->dump(fd);
-        }
-
-        if (mpPolicyManager) {
-            mpPolicyManager->dump(fd);
-        }
-
-        if (locked) mLock.unlock();
-    }
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::dumpPermissionDenial(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-    snprintf(buffer, SIZE, "Permission Denial: "
-            "can't dump AudioPolicyService from pid=%d, uid=%d\n",
-            IPCThreadState::self()->getCallingPid(),
-            IPCThreadState::self()->getCallingUid());
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    return BnAudioPolicyService::onTransact(code, data, reply, flags);
-}
-
-
-// ----------------------------------------------------------------------------
-void AudioPolicyService::instantiate() {
-    defaultServiceManager()->addService(
-            String16("media.audio_policy"), new AudioPolicyService());
-}
-
-
-// ----------------------------------------------------------------------------
-// AudioPolicyClientInterface implementation
-// ----------------------------------------------------------------------------
-
-
-audio_io_handle_t AudioPolicyService::openOutput(uint32_t *pDevices,
-                                uint32_t *pSamplingRate,
-                                uint32_t *pFormat,
-                                uint32_t *pChannels,
-                                uint32_t *pLatencyMs,
-                                AudioSystem::output_flags flags)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        LOGW("openOutput() could not get AudioFlinger");
-        return 0;
-    }
-
-    return af->openOutput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, pLatencyMs, flags);
-}
-
-audio_io_handle_t AudioPolicyService::openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        LOGW("openDuplicateOutput() could not get AudioFlinger");
-        return 0;
-    }
-    return af->openDuplicateOutput(output1, output2);
-}
-
-status_t AudioPolicyService::closeOutput(audio_io_handle_t output)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
-
-    return af->closeOutput(output);
-}
-
-
-status_t AudioPolicyService::suspendOutput(audio_io_handle_t output)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        LOGW("suspendOutput() could not get AudioFlinger");
-        return PERMISSION_DENIED;
-    }
-
-    return af->suspendOutput(output);
-}
-
-status_t AudioPolicyService::restoreOutput(audio_io_handle_t output)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        LOGW("restoreOutput() could not get AudioFlinger");
-        return PERMISSION_DENIED;
-    }
-
-    return af->restoreOutput(output);
-}
-
-audio_io_handle_t AudioPolicyService::openInput(uint32_t *pDevices,
-                                uint32_t *pSamplingRate,
-                                uint32_t *pFormat,
-                                uint32_t *pChannels,
-                                uint32_t acoustics)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) {
-        LOGW("openInput() could not get AudioFlinger");
-        return 0;
-    }
-
-    return af->openInput(pDevices, pSamplingRate, (uint32_t *)pFormat, pChannels, acoustics);
-}
-
-status_t AudioPolicyService::closeInput(audio_io_handle_t input)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
-
-    return af->closeInput(input);
-}
-
-status_t AudioPolicyService::setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs)
-{
-    return mAudioCommandThread->volumeCommand((int)stream, volume, (int)output, delayMs);
-}
-
-status_t AudioPolicyService::setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output)
-{
-    sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
-    if (af == 0) return PERMISSION_DENIED;
-
-    return af->setStreamOutput(stream, output);
-}
-
-
-void AudioPolicyService::setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs)
-{
-    mAudioCommandThread->parametersCommand((int)ioHandle, keyValuePairs, delayMs);
-}
-
-String8 AudioPolicyService::getParameters(audio_io_handle_t ioHandle, const String8& keys)
-{
-    String8 result = AudioSystem::getParameters(ioHandle, keys);
-    return result;
-}
-
-status_t AudioPolicyService::startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream)
-{
-    mTonePlaybackThread->startToneCommand(tone, stream);
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::stopTone()
-{
-    mTonePlaybackThread->stopToneCommand();
-    return NO_ERROR;
-}
-
-status_t AudioPolicyService::setVoiceVolume(float volume, int delayMs)
-{
-    return mAudioCommandThread->voiceVolumeCommand(volume, delayMs);
-}
-
-// -----------  AudioPolicyService::AudioCommandThread implementation ----------
-
-AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name)
-    : Thread(false), mName(name)
-{
-    mpToneGenerator = NULL;
-}
-
-
-AudioPolicyService::AudioCommandThread::~AudioCommandThread()
-{
-    if (mName != "" && !mAudioCommands.isEmpty()) {
-        release_wake_lock(mName.string());
-    }
-    mAudioCommands.clear();
-    if (mpToneGenerator != NULL) delete mpToneGenerator;
-}
-
-void AudioPolicyService::AudioCommandThread::onFirstRef()
-{
-    if (mName != "") {
-        run(mName.string(), ANDROID_PRIORITY_AUDIO);
-    } else {
-        run("AudioCommandThread", ANDROID_PRIORITY_AUDIO);
-    }
-}
-
-bool AudioPolicyService::AudioCommandThread::threadLoop()
-{
-    nsecs_t waitTime = INT64_MAX;
-
-    mLock.lock();
-    while (!exitPending())
-    {
-        while(!mAudioCommands.isEmpty()) {
-            nsecs_t curTime = systemTime();
-            // commands are sorted by increasing time stamp: execute them from index 0 and up
-            if (mAudioCommands[0]->mTime <= curTime) {
-                AudioCommand *command = mAudioCommands[0];
-                mAudioCommands.removeAt(0);
-                mLastCommand = *command;
-
-                switch (command->mCommand) {
-                case START_TONE: {
-                    mLock.unlock();
-                    ToneData *data = (ToneData *)command->mParam;
-                    LOGV("AudioCommandThread() processing start tone %d on stream %d",
-                            data->mType, data->mStream);
-                    if (mpToneGenerator != NULL)
-                        delete mpToneGenerator;
-                    mpToneGenerator = new ToneGenerator(data->mStream, 1.0);
-                    mpToneGenerator->startTone(data->mType);
-                    delete data;
-                    mLock.lock();
-                    }break;
-                case STOP_TONE: {
-                    mLock.unlock();
-                    LOGV("AudioCommandThread() processing stop tone");
-                    if (mpToneGenerator != NULL) {
-                        mpToneGenerator->stopTone();
-                        delete mpToneGenerator;
-                        mpToneGenerator = NULL;
-                    }
-                    mLock.lock();
-                    }break;
-                case SET_VOLUME: {
-                    VolumeData *data = (VolumeData *)command->mParam;
-                    LOGV("AudioCommandThread() processing set volume stream %d, volume %f, output %d", data->mStream, data->mVolume, data->mIO);
-                    command->mStatus = AudioSystem::setStreamVolume(data->mStream, data->mVolume, data->mIO);
-                    if (command->mWaitStatus) {
-                        command->mCond.signal();
-                        mWaitWorkCV.wait(mLock);
-                    }
-                    delete data;
-                    }break;
-                case SET_PARAMETERS: {
-                     ParametersData *data = (ParametersData *)command->mParam;
-                     LOGV("AudioCommandThread() processing set parameters string %s, io %d", data->mKeyValuePairs.string(), data->mIO);
-                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
-                     if (command->mWaitStatus) {
-                         command->mCond.signal();
-                         mWaitWorkCV.wait(mLock);
-                     }
-                     delete data;
-                     }break;
-                case SET_VOICE_VOLUME: {
-                    VoiceVolumeData *data = (VoiceVolumeData *)command->mParam;
-                    LOGV("AudioCommandThread() processing set voice volume volume %f", data->mVolume);
-                    command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
-                    if (command->mWaitStatus) {
-                        command->mCond.signal();
-                        mWaitWorkCV.wait(mLock);
-                    }
-                    delete data;
-                    }break;
-                default:
-                    LOGW("AudioCommandThread() unknown command %d", command->mCommand);
-                }
-                delete command;
-                waitTime = INT64_MAX;
-            } else {
-                waitTime = mAudioCommands[0]->mTime - curTime;
-                break;
-            }
-        }
-        // release delayed commands wake lock
-        if (mName != "" && mAudioCommands.isEmpty()) {
-            release_wake_lock(mName.string());
-        }
-        LOGV("AudioCommandThread() going to sleep");
-        mWaitWorkCV.waitRelative(mLock, waitTime);
-        LOGV("AudioCommandThread() waking up");
-    }
-    mLock.unlock();
-    return false;
-}
-
-status_t AudioPolicyService::AudioCommandThread::dump(int fd)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "AudioCommandThread %p Dump\n", this);
-    result.append(buffer);
-    write(fd, result.string(), result.size());
-
-    bool locked = tryLock(mLock);
-    if (!locked) {
-        String8 result2(kCmdDeadlockedString);
-        write(fd, result2.string(), result2.size());
-    }
-
-    snprintf(buffer, SIZE, "- Commands:\n");
-    result = String8(buffer);
-    result.append("   Command Time        Wait pParam\n");
-    for (int i = 0; i < (int)mAudioCommands.size(); i++) {
-        mAudioCommands[i]->dump(buffer, SIZE);
-        result.append(buffer);
-    }
-    result.append("  Last Command\n");
-    mLastCommand.dump(buffer, SIZE);
-    result.append(buffer);
-
-    write(fd, result.string(), result.size());
-
-    if (locked) mLock.unlock();
-
-    return NO_ERROR;
-}
-
-void AudioPolicyService::AudioCommandThread::startToneCommand(int type, int stream)
-{
-    AudioCommand *command = new AudioCommand();
-    command->mCommand = START_TONE;
-    ToneData *data = new ToneData();
-    data->mType = type;
-    data->mStream = stream;
-    command->mParam = (void *)data;
-    command->mWaitStatus = false;
-    Mutex::Autolock _l(mLock);
-    insertCommand_l(command);
-    LOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
-    mWaitWorkCV.signal();
-}
-
-void AudioPolicyService::AudioCommandThread::stopToneCommand()
-{
-    AudioCommand *command = new AudioCommand();
-    command->mCommand = STOP_TONE;
-    command->mParam = NULL;
-    command->mWaitStatus = false;
-    Mutex::Autolock _l(mLock);
-    insertCommand_l(command);
-    LOGV("AudioCommandThread() adding tone stop");
-    mWaitWorkCV.signal();
-}
-
-status_t AudioPolicyService::AudioCommandThread::volumeCommand(int stream, float volume, int output, int delayMs)
-{
-    status_t status = NO_ERROR;
-
-    AudioCommand *command = new AudioCommand();
-    command->mCommand = SET_VOLUME;
-    VolumeData *data = new VolumeData();
-    data->mStream = stream;
-    data->mVolume = volume;
-    data->mIO = output;
-    command->mParam = data;
-    if (delayMs == 0) {
-        command->mWaitStatus = true;
-    } else {
-        command->mWaitStatus = false;
-    }
-    Mutex::Autolock _l(mLock);
-    insertCommand_l(command, delayMs);
-    LOGV("AudioCommandThread() adding set volume stream %d, volume %f, output %d", stream, volume, output);
-    mWaitWorkCV.signal();
-    if (command->mWaitStatus) {
-        command->mCond.wait(mLock);
-        status =  command->mStatus;
-        mWaitWorkCV.signal();
-    }
-    return status;
-}
-
-status_t AudioPolicyService::AudioCommandThread::parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs)
-{
-    status_t status = NO_ERROR;
-
-    AudioCommand *command = new AudioCommand();
-    command->mCommand = SET_PARAMETERS;
-    ParametersData *data = new ParametersData();
-    data->mIO = ioHandle;
-    data->mKeyValuePairs = keyValuePairs;
-    command->mParam = data;
-    if (delayMs == 0) {
-        command->mWaitStatus = true;
-    } else {
-        command->mWaitStatus = false;
-    }
-    Mutex::Autolock _l(mLock);
-    insertCommand_l(command, delayMs);
-    LOGV("AudioCommandThread() adding set parameter string %s, io %d ,delay %d", keyValuePairs.string(), ioHandle, delayMs);
-    mWaitWorkCV.signal();
-    if (command->mWaitStatus) {
-        command->mCond.wait(mLock);
-        status =  command->mStatus;
-        mWaitWorkCV.signal();
-    }
-    return status;
-}
-
-status_t AudioPolicyService::AudioCommandThread::voiceVolumeCommand(float volume, int delayMs)
-{
-    status_t status = NO_ERROR;
-
-    AudioCommand *command = new AudioCommand();
-    command->mCommand = SET_VOICE_VOLUME;
-    VoiceVolumeData *data = new VoiceVolumeData();
-    data->mVolume = volume;
-    command->mParam = data;
-    if (delayMs == 0) {
-        command->mWaitStatus = true;
-    } else {
-        command->mWaitStatus = false;
-    }
-    Mutex::Autolock _l(mLock);
-    insertCommand_l(command, delayMs);
-    LOGV("AudioCommandThread() adding set voice volume volume %f", volume);
-    mWaitWorkCV.signal();
-    if (command->mWaitStatus) {
-        command->mCond.wait(mLock);
-        status =  command->mStatus;
-        mWaitWorkCV.signal();
-    }
-    return status;
-}
-
-// insertCommand_l() must be called with mLock held
-void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *command, int delayMs)
-{
-    ssize_t i;
-    Vector <AudioCommand *> removedCommands;
-
-    command->mTime = systemTime() + milliseconds(delayMs);
-
-    // acquire wake lock to make sure delayed commands are processed
-    if (mName != "" && mAudioCommands.isEmpty()) {
-        acquire_wake_lock(PARTIAL_WAKE_LOCK, mName.string());
-    }
-
-    // check same pending commands with later time stamps and eliminate them
-    for (i = mAudioCommands.size()-1; i >= 0; i--) {
-        AudioCommand *command2 = mAudioCommands[i];
-        // commands are sorted by increasing time stamp: no need to scan the rest of mAudioCommands
-        if (command2->mTime <= command->mTime) break;
-        if (command2->mCommand != command->mCommand) continue;
-
-        switch (command->mCommand) {
-        case SET_PARAMETERS: {
-            ParametersData *data = (ParametersData *)command->mParam;
-            ParametersData *data2 = (ParametersData *)command2->mParam;
-            if (data->mIO != data2->mIO) break;
-            LOGV("Comparing parameter command %s to new command %s", data2->mKeyValuePairs.string(), data->mKeyValuePairs.string());
-            AudioParameter param = AudioParameter(data->mKeyValuePairs);
-            AudioParameter param2 = AudioParameter(data2->mKeyValuePairs);
-            for (size_t j = 0; j < param.size(); j++) {
-               String8 key;
-               String8 value;
-               param.getAt(j, key, value);
-               for (size_t k = 0; k < param2.size(); k++) {
-                  String8 key2;
-                  String8 value2;
-                  param2.getAt(k, key2, value2);
-                  if (key2 == key) {
-                      param2.remove(key2);
-                      LOGV("Filtering out parameter %s", key2.string());
-                      break;
-                  }
-               }
-            }
-            // if all keys have been filtered out, remove the command.
-            // otherwise, update the key value pairs
-            if (param2.size() == 0) {
-                removedCommands.add(command2);
-            } else {
-                data2->mKeyValuePairs = param2.toString();
-            }
-        } break;
-
-        case SET_VOLUME: {
-            VolumeData *data = (VolumeData *)command->mParam;
-            VolumeData *data2 = (VolumeData *)command2->mParam;
-            if (data->mIO != data2->mIO) break;
-            if (data->mStream != data2->mStream) break;
-            LOGV("Filtering out volume command on output %d for stream %d", data->mIO, data->mStream);
-            removedCommands.add(command2);
-        } break;
-        case START_TONE:
-        case STOP_TONE:
-        default:
-            break;
-        }
-    }
-
-    // remove filtered commands
-    for (size_t j = 0; j < removedCommands.size(); j++) {
-        // removed commands always have time stamps greater than current command
-        for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
-            if (mAudioCommands[k] == removedCommands[j]) {
-                LOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
-                mAudioCommands.removeAt(k);
-                break;
-            }
-        }
-    }
-    removedCommands.clear();
-
-    // insert command at the right place according to its time stamp
-    LOGV("inserting command: %d at index %d, num commands %d", command->mCommand, (int)i+1, mAudioCommands.size());
-    mAudioCommands.insertAt(command, i + 1);
-}
-
-void AudioPolicyService::AudioCommandThread::exit()
-{
-    LOGV("AudioCommandThread::exit");
-    {
-        AutoMutex _l(mLock);
-        requestExit();
-        mWaitWorkCV.signal();
-    }
-    requestExitAndWait();
-}
-
-void AudioPolicyService::AudioCommandThread::AudioCommand::dump(char* buffer, size_t size)
-{
-    snprintf(buffer, size, "   %02d      %06d.%03d  %01u    %p\n",
-            mCommand,
-            (int)ns2s(mTime),
-            (int)ns2ms(mTime)%1000,
-            mWaitStatus,
-            mParam);
-}
-
-}; // namespace android
diff --git a/libs/audioflinger/AudioPolicyService.h b/libs/audioflinger/AudioPolicyService.h
deleted file mode 100644
index a13d0bd..0000000
--- a/libs/audioflinger/AudioPolicyService.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright (C) 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_AUDIOPOLICYSERVICE_H
-#define ANDROID_AUDIOPOLICYSERVICE_H
-
-#include <media/IAudioPolicyService.h>
-#include <hardware_legacy/AudioPolicyInterface.h>
-#include <media/ToneGenerator.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-class String8;
-
-// ----------------------------------------------------------------------------
-
-class AudioPolicyService: public BnAudioPolicyService, public AudioPolicyClientInterface, public IBinder::DeathRecipient
-{
-
-public:
-    static  void        instantiate();
-
-    virtual status_t    dump(int fd, const Vector<String16>& args);
-
-    //
-    // BnAudioPolicyService (see AudioPolicyInterface for method descriptions)
-    //
-
-    virtual status_t setDeviceConnectionState(AudioSystem::audio_devices device,
-                                              AudioSystem::device_connection_state state,
-                                              const char *device_address);
-    virtual AudioSystem::device_connection_state getDeviceConnectionState(AudioSystem::audio_devices device,
-                                                                          const char *device_address);
-    virtual status_t setPhoneState(int state);
-    virtual status_t setRingerMode(uint32_t mode, uint32_t mask);
-    virtual status_t setForceUse(AudioSystem::force_use usage, AudioSystem::forced_config config);
-    virtual AudioSystem::forced_config getForceUse(AudioSystem::force_use usage);
-    virtual audio_io_handle_t getOutput(AudioSystem::stream_type stream,
-                                        uint32_t samplingRate = 0,
-                                        uint32_t format = AudioSystem::FORMAT_DEFAULT,
-                                        uint32_t channels = 0,
-                                        AudioSystem::output_flags flags = AudioSystem::OUTPUT_FLAG_INDIRECT);
-    virtual status_t startOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
-    virtual status_t stopOutput(audio_io_handle_t output, AudioSystem::stream_type stream);
-    virtual void releaseOutput(audio_io_handle_t output);
-    virtual audio_io_handle_t getInput(int inputSource,
-                                    uint32_t samplingRate = 0,
-                                    uint32_t format = AudioSystem::FORMAT_DEFAULT,
-                                    uint32_t channels = 0,
-                                    AudioSystem::audio_in_acoustics acoustics = (AudioSystem::audio_in_acoustics)0);
-    virtual status_t startInput(audio_io_handle_t input);
-    virtual status_t stopInput(audio_io_handle_t input);
-    virtual void releaseInput(audio_io_handle_t input);
-    virtual status_t initStreamVolume(AudioSystem::stream_type stream,
-                                      int indexMin,
-                                      int indexMax);
-    virtual status_t setStreamVolumeIndex(AudioSystem::stream_type stream, int index);
-    virtual status_t getStreamVolumeIndex(AudioSystem::stream_type stream, int *index);
-
-    virtual     status_t    onTransact(
-                                uint32_t code,
-                                const Parcel& data,
-                                Parcel* reply,
-                                uint32_t flags);
-
-    // IBinder::DeathRecipient
-    virtual     void        binderDied(const wp<IBinder>& who);
-
-    //
-    // AudioPolicyClientInterface
-    //
-    virtual audio_io_handle_t openOutput(uint32_t *pDevices,
-                                    uint32_t *pSamplingRate,
-                                    uint32_t *pFormat,
-                                    uint32_t *pChannels,
-                                    uint32_t *pLatencyMs,
-                                    AudioSystem::output_flags flags);
-    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2);
-    virtual status_t closeOutput(audio_io_handle_t output);
-    virtual status_t suspendOutput(audio_io_handle_t output);
-    virtual status_t restoreOutput(audio_io_handle_t output);
-    virtual audio_io_handle_t openInput(uint32_t *pDevices,
-                                    uint32_t *pSamplingRate,
-                                    uint32_t *pFormat,
-                                    uint32_t *pChannels,
-                                    uint32_t acoustics);
-    virtual status_t closeInput(audio_io_handle_t input);
-    virtual status_t setStreamVolume(AudioSystem::stream_type stream, float volume, audio_io_handle_t output, int delayMs = 0);
-    virtual status_t setStreamOutput(AudioSystem::stream_type stream, audio_io_handle_t output);
-    virtual void setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs, int delayMs = 0);
-    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys);
-    virtual status_t startTone(ToneGenerator::tone_type tone, AudioSystem::stream_type stream);
-    virtual status_t stopTone();
-    virtual status_t setVoiceVolume(float volume, int delayMs = 0);
-
-private:
-                        AudioPolicyService();
-    virtual             ~AudioPolicyService();
-
-            status_t dumpInternals(int fd);
-
-    // Thread used for tone playback and to send audio config commands to audio flinger
-    // For tone playback, using a separate thread is necessary to avoid deadlock with mLock because startTone()
-    // and stopTone() are normally called with mLock locked and requesting a tone start or stop will cause
-    // calls to AudioPolicyService and an attempt to lock mLock.
-    // For audio config commands, it is necessary because audio flinger requires that the calling process (user)
-    // has permission to modify audio settings.
-    class AudioCommandThread : public Thread {
-        class AudioCommand;
-    public:
-
-        // commands for tone AudioCommand
-        enum {
-            START_TONE,
-            STOP_TONE,
-            SET_VOLUME,
-            SET_PARAMETERS,
-            SET_VOICE_VOLUME
-        };
-
-        AudioCommandThread (String8 name);
-        virtual             ~AudioCommandThread();
-
-                    status_t    dump(int fd);
-
-        // Thread virtuals
-        virtual     void        onFirstRef();
-        virtual     bool        threadLoop();
-
-                    void        exit();
-                    void        startToneCommand(int type = 0, int stream = 0);
-                    void        stopToneCommand();
-                    status_t    volumeCommand(int stream, float volume, int output, int delayMs = 0);
-                    status_t    parametersCommand(int ioHandle, const String8& keyValuePairs, int delayMs = 0);
-                    status_t    voiceVolumeCommand(float volume, int delayMs = 0);
-                    void        insertCommand_l(AudioCommand *command, int delayMs = 0);
-
-    private:
-        // descriptor for requested tone playback event
-        class AudioCommand {
-
-        public:
-            AudioCommand()
-            : mCommand(-1) {}
-
-            void dump(char* buffer, size_t size);
-
-            int mCommand;   // START_TONE, STOP_TONE ...
-            nsecs_t mTime;  // time stamp
-            Condition mCond; // condition for status return
-            status_t mStatus; // command status
-            bool mWaitStatus; // true if caller is waiting for status
-            void *mParam;     // command parameter (ToneData, VolumeData, ParametersData)
-        };
-
-        class ToneData {
-        public:
-            int mType;      // tone type (START_TONE only)
-            int mStream;    // stream type (START_TONE only)
-        };
-
-        class VolumeData {
-        public:
-            int mStream;
-            float mVolume;
-            int mIO;
-        };
-
-        class ParametersData {
-        public:
-            int mIO;
-            String8 mKeyValuePairs;
-        };
-
-        class VoiceVolumeData {
-        public:
-            float mVolume;
-        };
-
-        Mutex   mLock;
-        Condition mWaitWorkCV;
-        Vector <AudioCommand *> mAudioCommands; // list of pending commands
-        ToneGenerator *mpToneGenerator;     // the tone generator
-        AudioCommand mLastCommand;          // last processed command (used by dump)
-        String8 mName;                      // string used by wake lock fo delayed commands
-    };
-
-    // Internal dump utilities.
-    status_t dumpPermissionDenial(int fd);
-
-
-    Mutex   mLock;      // prevents concurrent access to AudioPolicy manager functions changing device
-                        // connection stated our routing
-    AudioPolicyInterface* mpPolicyManager;          // the platform specific policy manager
-    sp <AudioCommandThread> mAudioCommandThread;    // audio commands thread
-    sp <AudioCommandThread> mTonePlaybackThread;     // tone playback thread
-};
-
-}; // namespace android
-
-#endif // ANDROID_AUDIOPOLICYSERVICE_H
-
-
-
-
-
-
-
-
diff --git a/libs/audioflinger/AudioResampler.cpp b/libs/audioflinger/AudioResampler.cpp
deleted file mode 100644
index 5dabacb..0000000
--- a/libs/audioflinger/AudioResampler.cpp
+++ /dev/null
@@ -1,595 +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.
- */
-
-#define LOG_TAG "AudioResampler"
-//#define LOG_NDEBUG 0
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-#include <cutils/properties.h>
-#include "AudioResampler.h"
-#include "AudioResamplerSinc.h"
-#include "AudioResamplerCubic.h"
-
-namespace android {
-
-#ifdef __ARM_ARCH_5E__  // optimized asm option
-    #define ASM_ARM_RESAMP1 // enable asm optimisation for ResamplerOrder1
-#endif // __ARM_ARCH_5E__
-// ----------------------------------------------------------------------------
-
-class AudioResamplerOrder1 : public AudioResampler {
-public:
-    AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
-        AudioResampler(bitDepth, inChannelCount, sampleRate), mX0L(0), mX0R(0) {
-    }
-    virtual void resample(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-private:
-    // number of bits used in interpolation multiply - 15 bits avoids overflow
-    static const int kNumInterpBits = 15;
-
-    // bits to shift the phase fraction down to avoid overflow
-    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
-
-    void init() {}
-    void resampleMono16(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-    void resampleStereo16(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
-    void AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
-            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
-            uint32_t &phaseFraction, uint32_t phaseIncrement);
-    void AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
-            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
-            uint32_t &phaseFraction, uint32_t phaseIncrement);
-#endif  // ASM_ARM_RESAMP1
-
-    static inline int32_t Interp(int32_t x0, int32_t x1, uint32_t f) {
-        return x0 + (((x1 - x0) * (int32_t)(f >> kPreInterpShift)) >> kNumInterpBits);
-    }
-    static inline void Advance(size_t* index, uint32_t* frac, uint32_t inc) {
-        *frac += inc;
-        *index += (size_t)(*frac >> kNumPhaseBits);
-        *frac &= kPhaseMask;
-    }
-    int mX0L;
-    int mX0R;
-};
-
-// ----------------------------------------------------------------------------
-AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
-        int32_t sampleRate, int quality) {
-
-    // can only create low quality resample now
-    AudioResampler* resampler;
-
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("af.resampler.quality", value, 0)) {
-        quality = atoi(value);
-        LOGD("forcing AudioResampler quality to %d", quality);
-    }
-
-    if (quality == DEFAULT)
-        quality = LOW_QUALITY;
-
-    switch (quality) {
-    default:
-    case LOW_QUALITY:
-        LOGV("Create linear Resampler");
-        resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
-        break;
-    case MED_QUALITY:
-        LOGV("Create cubic Resampler");
-        resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
-        break;
-    case HIGH_QUALITY:
-        LOGV("Create sinc Resampler");
-        resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
-        break;
-    }
-
-    // initialize resampler
-    resampler->init();
-    return resampler;
-}
-
-AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
-        int32_t sampleRate) :
-    mBitDepth(bitDepth), mChannelCount(inChannelCount),
-            mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
-            mPhaseFraction(0) {
-    // sanity check on format
-    if ((bitDepth != 16) ||(inChannelCount < 1) || (inChannelCount > 2)) {
-        LOGE("Unsupported sample format, %d bits, %d channels", bitDepth,
-                inChannelCount);
-        // LOG_ASSERT(0);
-    }
-
-    // initialize common members
-    mVolume[0] = mVolume[1] = 0;
-    mBuffer.frameCount = 0;
-
-    // save format for quick lookup
-    if (inChannelCount == 1) {
-        mFormat = MONO_16_BIT;
-    } else {
-        mFormat = STEREO_16_BIT;
-    }
-}
-
-AudioResampler::~AudioResampler() {
-}
-
-void AudioResampler::setSampleRate(int32_t inSampleRate) {
-    mInSampleRate = inSampleRate;
-    mPhaseIncrement = (uint32_t)((kPhaseMultiplier * inSampleRate) / mSampleRate);
-}
-
-void AudioResampler::setVolume(int16_t left, int16_t right) {
-    // TODO: Implement anti-zipper filter
-    mVolume[0] = left;
-    mVolume[1] = right;
-}
-
-// ----------------------------------------------------------------------------
-
-void AudioResamplerOrder1::resample(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider) {
-
-    // should never happen, but we overflow if it does
-    // LOG_ASSERT(outFrameCount < 32767);
-
-    // select the appropriate resampler
-    switch (mChannelCount) {
-    case 1:
-        resampleMono16(out, outFrameCount, provider);
-        break;
-    case 2:
-        resampleStereo16(out, outFrameCount, provider);
-        break;
-    }
-}
-
-void AudioResamplerOrder1::resampleStereo16(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider) {
-
-    int32_t vl = mVolume[0];
-    int32_t vr = mVolume[1];
-
-    size_t inputIndex = mInputIndex;
-    uint32_t phaseFraction = mPhaseFraction;
-    uint32_t phaseIncrement = mPhaseIncrement;
-    size_t outputIndex = 0;
-    size_t outputSampleCount = outFrameCount * 2;
-    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
-    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
-    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
-
-    while (outputIndex < outputSampleCount) {
-
-        // buffer is empty, fetch a new one
-        while (mBuffer.frameCount == 0) {
-            mBuffer.frameCount = inFrameCount;
-            provider->getNextBuffer(&mBuffer);
-            if (mBuffer.raw == NULL) {
-                goto resampleStereo16_exit;
-            }
-
-            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
-            if (mBuffer.frameCount > inputIndex) break;
-
-            inputIndex -= mBuffer.frameCount;
-            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
-            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
-            provider->releaseBuffer(&mBuffer);
-             // mBuffer.frameCount == 0 now so we reload a new buffer
-        }
-
-        int16_t *in = mBuffer.i16;
-
-        // handle boundary case
-        while (inputIndex == 0) {
-            // LOGE("boundary case\n");
-            out[outputIndex++] += vl * Interp(mX0L, in[0], phaseFraction);
-            out[outputIndex++] += vr * Interp(mX0R, in[1], phaseFraction);
-            Advance(&inputIndex, &phaseFraction, phaseIncrement);
-            if (outputIndex == outputSampleCount)
-                break;
-        }
-
-        // process input samples
-        // LOGE("general case\n");
-
-#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
-        if (inputIndex + 2 < mBuffer.frameCount) {
-            int32_t* maxOutPt;
-            int32_t maxInIdx;
-
-            maxOutPt = out + (outputSampleCount - 2);   // 2 because 2 frames per loop
-            maxInIdx = mBuffer.frameCount - 2;
-            AsmStereo16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
-                    phaseFraction, phaseIncrement);
-        }
-#endif  // ASM_ARM_RESAMP1
-
-        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
-            out[outputIndex++] += vl * Interp(in[inputIndex*2-2],
-                    in[inputIndex*2], phaseFraction);
-            out[outputIndex++] += vr * Interp(in[inputIndex*2-1],
-                    in[inputIndex*2+1], phaseFraction);
-            Advance(&inputIndex, &phaseFraction, phaseIncrement);
-        }
-
-        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
-        // if done with buffer, save samples
-        if (inputIndex >= mBuffer.frameCount) {
-            inputIndex -= mBuffer.frameCount;
-
-            // LOGE("buffer done, new input index %d", inputIndex);
-
-            mX0L = mBuffer.i16[mBuffer.frameCount*2-2];
-            mX0R = mBuffer.i16[mBuffer.frameCount*2-1];
-            provider->releaseBuffer(&mBuffer);
-
-            // verify that the releaseBuffer resets the buffer frameCount
-            // LOG_ASSERT(mBuffer.frameCount == 0);
-        }
-    }
-
-    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
-resampleStereo16_exit:
-    // save state
-    mInputIndex = inputIndex;
-    mPhaseFraction = phaseFraction;
-}
-
-void AudioResamplerOrder1::resampleMono16(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider) {
-
-    int32_t vl = mVolume[0];
-    int32_t vr = mVolume[1];
-
-    size_t inputIndex = mInputIndex;
-    uint32_t phaseFraction = mPhaseFraction;
-    uint32_t phaseIncrement = mPhaseIncrement;
-    size_t outputIndex = 0;
-    size_t outputSampleCount = outFrameCount * 2;
-    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
-    // LOGE("starting resample %d frames, inputIndex=%d, phaseFraction=%d, phaseIncrement=%d\n",
-    //      outFrameCount, inputIndex, phaseFraction, phaseIncrement);
-    while (outputIndex < outputSampleCount) {
-        // buffer is empty, fetch a new one
-        while (mBuffer.frameCount == 0) {
-            mBuffer.frameCount = inFrameCount;
-            provider->getNextBuffer(&mBuffer);
-            if (mBuffer.raw == NULL) {
-                mInputIndex = inputIndex;
-                mPhaseFraction = phaseFraction;
-                goto resampleMono16_exit;
-            }
-            // LOGE("New buffer fetched: %d frames\n", mBuffer.frameCount);
-            if (mBuffer.frameCount >  inputIndex) break;
-
-            inputIndex -= mBuffer.frameCount;
-            mX0L = mBuffer.i16[mBuffer.frameCount-1];
-            provider->releaseBuffer(&mBuffer);
-            // mBuffer.frameCount == 0 now so we reload a new buffer
-        }
-        int16_t *in = mBuffer.i16;
-
-        // handle boundary case
-        while (inputIndex == 0) {
-            // LOGE("boundary case\n");
-            int32_t sample = Interp(mX0L, in[0], phaseFraction);
-            out[outputIndex++] += vl * sample;
-            out[outputIndex++] += vr * sample;
-            Advance(&inputIndex, &phaseFraction, phaseIncrement);
-            if (outputIndex == outputSampleCount)
-                break;
-        }
-
-        // process input samples
-        // LOGE("general case\n");
-
-#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
-        if (inputIndex + 2 < mBuffer.frameCount) {
-            int32_t* maxOutPt;
-            int32_t maxInIdx;
-
-            maxOutPt = out + (outputSampleCount - 2);
-            maxInIdx = (int32_t)mBuffer.frameCount - 2;
-                AsmMono16Loop(in, maxOutPt, maxInIdx, outputIndex, out, inputIndex, vl, vr,
-                        phaseFraction, phaseIncrement);
-        }
-#endif  // ASM_ARM_RESAMP1
-
-        while (outputIndex < outputSampleCount && inputIndex < mBuffer.frameCount) {
-            int32_t sample = Interp(in[inputIndex-1], in[inputIndex],
-                    phaseFraction);
-            out[outputIndex++] += vl * sample;
-            out[outputIndex++] += vr * sample;
-            Advance(&inputIndex, &phaseFraction, phaseIncrement);
-        }
-
-
-        // LOGE("loop done - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
-        // if done with buffer, save samples
-        if (inputIndex >= mBuffer.frameCount) {
-            inputIndex -= mBuffer.frameCount;
-
-            // LOGE("buffer done, new input index %d", inputIndex);
-
-            mX0L = mBuffer.i16[mBuffer.frameCount-1];
-            provider->releaseBuffer(&mBuffer);
-
-            // verify that the releaseBuffer resets the buffer frameCount
-            // LOG_ASSERT(mBuffer.frameCount == 0);
-        }
-    }
-
-    // LOGE("output buffer full - outputIndex=%d, inputIndex=%d\n", outputIndex, inputIndex);
-
-resampleMono16_exit:
-    // save state
-    mInputIndex = inputIndex;
-    mPhaseFraction = phaseFraction;
-}
-
-#ifdef ASM_ARM_RESAMP1  // asm optimisation for ResamplerOrder1
-
-/*******************************************************************
-*
-*   AsmMono16Loop
-*   asm optimized monotonic loop version; one loop is 2 frames
-*   Input:
-*       in : pointer on input samples
-*       maxOutPt : pointer on first not filled
-*       maxInIdx : index on first not used
-*       outputIndex : pointer on current output index
-*       out : pointer on output buffer
-*       inputIndex : pointer on current input index
-*       vl, vr : left and right gain
-*       phaseFraction : pointer on current phase fraction
-*       phaseIncrement
-*   Ouput:
-*       outputIndex :
-*       out : updated buffer
-*       inputIndex : index of next to use
-*       phaseFraction : phase fraction for next interpolation
-*
-*******************************************************************/
-void AudioResamplerOrder1::AsmMono16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
-            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
-            uint32_t &phaseFraction, uint32_t phaseIncrement)
-{
-#define MO_PARAM5   "36"        // offset of parameter 5 (outputIndex)
-
-    asm(
-        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, lr}\n"
-        // get parameters
-        "   ldr r6, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
-        "   ldr r6, [r6]\n"                         // phaseFraction
-        "   ldr r7, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
-        "   ldr r7, [r7]\n"                         // inputIndex
-        "   ldr r8, [sp, #" MO_PARAM5 " + 4]\n"     // out
-        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
-        "   ldr r0, [r0]\n"                         // outputIndex
-        "   add r8, r0, asl #2\n"                   // curOut
-        "   ldr r9, [sp, #" MO_PARAM5 " + 24]\n"    // phaseIncrement
-        "   ldr r10, [sp, #" MO_PARAM5 " + 12]\n"   // vl
-        "   ldr r11, [sp, #" MO_PARAM5 " + 16]\n"   // vr
-
-        // r0 pin, x0, Samp
-
-        // r1 in
-        // r2 maxOutPt
-        // r3 maxInIdx
-
-        // r4 x1, i1, i3, Out1
-        // r5 out0
-
-        // r6 frac
-        // r7 inputIndex
-        // r8 curOut
-
-        // r9 inc
-        // r10 vl
-        // r11 vr
-
-        // r12
-        // r13 sp
-        // r14
-
-        // the following loop works on 2 frames
-
-        ".Y4L01:\n"
-        "   cmp r8, r2\n"                   // curOut - maxCurOut
-        "   bcs .Y4L02\n"
-
-#define MO_ONE_FRAME \
-    "   add r0, r1, r7, asl #1\n"       /* in + inputIndex */\
-    "   ldrsh r4, [r0]\n"               /* in[inputIndex] */\
-    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
-    "   ldrsh r0, [r0, #-2]\n"          /* in[inputIndex-1] */\
-    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
-    "   sub r4, r4, r0\n"               /* in[inputIndex] - in[inputIndex-1] */\
-    "   mov r4, r4, lsl #2\n"           /* <<2 */\
-    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
-    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
-    "   add r0, r0, r4\n"               /* x0 - (..) */\
-    "   mla r5, r0, r10, r5\n"          /* vl*interp + out[] */\
-    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
-    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
-    "   mla r4, r0, r11, r4\n"          /* vr*interp + out[] */\
-    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */\
-    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */
-
-        MO_ONE_FRAME    // frame 1
-        MO_ONE_FRAME    // frame 2
-
-        "   cmp r7, r3\n"                   // inputIndex - maxInIdx
-        "   bcc .Y4L01\n"
-        ".Y4L02:\n"
-
-        "   bic r6, r6, #0xC0000000\n"             // phaseFraction & ...
-        // save modified values
-        "   ldr r0, [sp, #" MO_PARAM5 " + 20]\n"    // &phaseFraction
-        "   str r6, [r0]\n"                         // phaseFraction
-        "   ldr r0, [sp, #" MO_PARAM5 " + 8]\n"     // &inputIndex
-        "   str r7, [r0]\n"                         // inputIndex
-        "   ldr r0, [sp, #" MO_PARAM5 " + 4]\n"     // out
-        "   sub r8, r0\n"                           // curOut - out
-        "   asr r8, #2\n"                           // new outputIndex
-        "   ldr r0, [sp, #" MO_PARAM5 " + 0]\n"     // &outputIndex
-        "   str r8, [r0]\n"                         // save outputIndex
-
-        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, pc}\n"
-    );
-}
-
-/*******************************************************************
-*
-*   AsmStereo16Loop
-*   asm optimized stereo loop version; one loop is 2 frames
-*   Input:
-*       in : pointer on input samples
-*       maxOutPt : pointer on first not filled
-*       maxInIdx : index on first not used
-*       outputIndex : pointer on current output index
-*       out : pointer on output buffer
-*       inputIndex : pointer on current input index
-*       vl, vr : left and right gain
-*       phaseFraction : pointer on current phase fraction
-*       phaseIncrement
-*   Ouput:
-*       outputIndex :
-*       out : updated buffer
-*       inputIndex : index of next to use
-*       phaseFraction : phase fraction for next interpolation
-*
-*******************************************************************/
-void AudioResamplerOrder1::AsmStereo16Loop(int16_t *in, int32_t* maxOutPt, int32_t maxInIdx,
-            size_t &outputIndex, int32_t* out, size_t &inputIndex, int32_t vl, int32_t vr,
-            uint32_t &phaseFraction, uint32_t phaseIncrement)
-{
-#define ST_PARAM5    "40"     // offset of parameter 5 (outputIndex)
-    asm(
-        "stmfd  sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, lr}\n"
-        // get parameters
-        "   ldr r6, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
-        "   ldr r6, [r6]\n"                         // phaseFraction
-        "   ldr r7, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
-        "   ldr r7, [r7]\n"                         // inputIndex
-        "   ldr r8, [sp, #" ST_PARAM5 " + 4]\n"     // out
-        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
-        "   ldr r0, [r0]\n"                         // outputIndex
-        "   add r8, r0, asl #2\n"                   // curOut
-        "   ldr r9, [sp, #" ST_PARAM5 " + 24]\n"    // phaseIncrement
-        "   ldr r10, [sp, #" ST_PARAM5 " + 12]\n"   // vl
-        "   ldr r11, [sp, #" ST_PARAM5 " + 16]\n"   // vr
-
-        // r0 pin, x0, Samp
-
-        // r1 in
-        // r2 maxOutPt
-        // r3 maxInIdx
-
-        // r4 x1, i1, i3, out1
-        // r5 out0
-
-        // r6 frac
-        // r7 inputIndex
-        // r8 curOut
-
-        // r9 inc
-        // r10 vl
-        // r11 vr
-
-        // r12 temporary
-        // r13 sp
-        // r14
-
-        ".Y5L01:\n"
-        "   cmp r8, r2\n"                   // curOut - maxCurOut
-        "   bcs .Y5L02\n"
-
-#define ST_ONE_FRAME \
-    "   bic r6, r6, #0xC0000000\n"      /* phaseFraction & ... */\
-\
-    "   add r0, r1, r7, asl #2\n"       /* in + 2*inputIndex */\
-\
-    "   ldrsh r4, [r0]\n"               /* in[2*inputIndex] */\
-    "   ldr r5, [r8]\n"                 /* out[outputIndex] */\
-    "   ldrsh r12, [r0, #-4]\n"         /* in[2*inputIndex-2] */\
-    "   sub r4, r4, r12\n"              /* in[2*InputIndex] - in[2*InputIndex-2] */\
-    "   mov r4, r4, lsl #2\n"           /* <<2 */\
-    "   smulwt r4, r4, r6\n"            /* (x1-x0)*.. */\
-    "   add r12, r12, r4\n"             /* x0 - (..) */\
-    "   mla r5, r12, r10, r5\n"         /* vl*interp + out[] */\
-    "   ldr r4, [r8, #4]\n"             /* out[outputIndex+1] */\
-    "   str r5, [r8], #4\n"             /* out[outputIndex++] = ... */\
-\
-    "   ldrsh r12, [r0, #+2]\n"         /* in[2*inputIndex+1] */\
-    "   ldrsh r0, [r0, #-2]\n"          /* in[2*inputIndex-1] */\
-    "   sub r12, r12, r0\n"             /* in[2*InputIndex] - in[2*InputIndex-2] */\
-    "   mov r12, r12, lsl #2\n"         /* <<2 */\
-    "   smulwt r12, r12, r6\n"          /* (x1-x0)*.. */\
-    "   add r12, r0, r12\n"             /* x0 - (..) */\
-    "   mla r4, r12, r11, r4\n"         /* vr*interp + out[] */\
-    "   str r4, [r8], #4\n"             /* out[outputIndex++] = ... */\
-\
-    "   add r6, r6, r9\n"               /* phaseFraction + phaseIncrement */\
-    "   add r7, r7, r6, lsr #30\n"      /* inputIndex + phaseFraction>>30 */
-
-    ST_ONE_FRAME    // frame 1
-    ST_ONE_FRAME    // frame 1
-
-        "   cmp r7, r3\n"                       // inputIndex - maxInIdx
-        "   bcc .Y5L01\n"
-        ".Y5L02:\n"
-
-        "   bic r6, r6, #0xC0000000\n"              // phaseFraction & ...
-        // save modified values
-        "   ldr r0, [sp, #" ST_PARAM5 " + 20]\n"    // &phaseFraction
-        "   str r6, [r0]\n"                         // phaseFraction
-        "   ldr r0, [sp, #" ST_PARAM5 " + 8]\n"     // &inputIndex
-        "   str r7, [r0]\n"                         // inputIndex
-        "   ldr r0, [sp, #" ST_PARAM5 " + 4]\n"     // out
-        "   sub r8, r0\n"                           // curOut - out
-        "   asr r8, #2\n"                           // new outputIndex
-        "   ldr r0, [sp, #" ST_PARAM5 " + 0]\n"     // &outputIndex
-        "   str r8, [r0]\n"                         // save outputIndex
-
-        "   ldmfd   sp!, {r4, r5, r6, r7, r8, r9, r10, r11, r12, pc}\n"
-    );
-}
-
-#endif  // ASM_ARM_RESAMP1
-
-
-// ----------------------------------------------------------------------------
-}
-; // namespace android
-
diff --git a/libs/audioflinger/AudioResampler.h b/libs/audioflinger/AudioResampler.h
deleted file mode 100644
index 2dfac76..0000000
--- a/libs/audioflinger/AudioResampler.h
+++ /dev/null
@@ -1,93 +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_AUDIO_RESAMPLER_H
-#define ANDROID_AUDIO_RESAMPLER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "AudioBufferProvider.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-class AudioResampler {
-public:
-    // Determines quality of SRC.
-    //  LOW_QUALITY: linear interpolator (1st order)
-    //  MED_QUALITY: cubic interpolator (3rd order)
-    //  HIGH_QUALITY: fixed multi-tap FIR (e.g. 48KHz->44.1KHz)
-    // NOTE: high quality SRC will only be supported for
-    // certain fixed rate conversions. Sample rate cannot be
-    // changed dynamically. 
-    enum src_quality {
-        DEFAULT=0,
-        LOW_QUALITY=1,
-        MED_QUALITY=2,
-        HIGH_QUALITY=3
-    };
-
-    static AudioResampler* create(int bitDepth, int inChannelCount,
-            int32_t sampleRate, int quality=DEFAULT);
-
-    virtual ~AudioResampler();
-
-    virtual void init() = 0;
-    virtual void setSampleRate(int32_t inSampleRate);
-    virtual void setVolume(int16_t left, int16_t right);
-
-    virtual void resample(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider) = 0;
-
-protected:
-    // number of bits for phase fraction - 30 bits allows nearly 2x downsampling
-    static const int kNumPhaseBits = 30;
-
-    // phase mask for fraction
-    static const uint32_t kPhaseMask = (1LU<<kNumPhaseBits)-1;
-
-    // multiplier to calculate fixed point phase increment
-    static const double kPhaseMultiplier = 1L << kNumPhaseBits;
-
-    enum format {MONO_16_BIT, STEREO_16_BIT};
-    AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate);
-
-    // prevent copying
-    AudioResampler(const AudioResampler&);
-    AudioResampler& operator=(const AudioResampler&);
-
-    int32_t mBitDepth;
-    int32_t mChannelCount;
-    int32_t mSampleRate;
-    int32_t mInSampleRate;
-    AudioBufferProvider::Buffer mBuffer;
-    union {
-        int16_t mVolume[2];
-        uint32_t mVolumeRL;
-    };
-    int16_t mTargetVolume[2];
-    format mFormat;
-    size_t mInputIndex;
-    int32_t mPhaseIncrement;
-    uint32_t mPhaseFraction;
-};
-
-// ----------------------------------------------------------------------------
-}
-; // namespace android
-
-#endif // ANDROID_AUDIO_RESAMPLER_H
diff --git a/libs/audioflinger/AudioResamplerCubic.cpp b/libs/audioflinger/AudioResamplerCubic.cpp
deleted file mode 100644
index 1d247bd..0000000
--- a/libs/audioflinger/AudioResamplerCubic.cpp
+++ /dev/null
@@ -1,184 +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 <stdint.h>
-#include <string.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-
-#include "AudioResampler.h"
-#include "AudioResamplerCubic.h"
-
-#define LOG_TAG "AudioSRC"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-void AudioResamplerCubic::init() {
-    memset(&left, 0, sizeof(state));
-    memset(&right, 0, sizeof(state));
-}
-
-void AudioResamplerCubic::resample(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider) {
-
-    // should never happen, but we overflow if it does
-    // LOG_ASSERT(outFrameCount < 32767);
-
-    // select the appropriate resampler
-    switch (mChannelCount) {
-    case 1:
-        resampleMono16(out, outFrameCount, provider);
-        break;
-    case 2:
-        resampleStereo16(out, outFrameCount, provider);
-        break;
-    }
-}
-
-void AudioResamplerCubic::resampleStereo16(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider) {
-
-    int32_t vl = mVolume[0];
-    int32_t vr = mVolume[1];
-
-    size_t inputIndex = mInputIndex;
-    uint32_t phaseFraction = mPhaseFraction;
-    uint32_t phaseIncrement = mPhaseIncrement;
-    size_t outputIndex = 0;
-    size_t outputSampleCount = outFrameCount * 2;
-    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
-    // fetch first buffer
-    if (mBuffer.frameCount == 0) {
-        mBuffer.frameCount = inFrameCount;
-        provider->getNextBuffer(&mBuffer);
-        if (mBuffer.raw == NULL)
-            return;
-        // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
-    }
-    int16_t *in = mBuffer.i16;
-
-    while (outputIndex < outputSampleCount) {
-        int32_t sample;
-        int32_t x;
-
-        // calculate output sample
-        x = phaseFraction >> kPreInterpShift;
-        out[outputIndex++] += vl * interp(&left, x);
-        out[outputIndex++] += vr * interp(&right, x);
-        // out[outputIndex++] += vr * in[inputIndex*2];
-
-        // increment phase
-        phaseFraction += phaseIncrement;
-        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
-        phaseFraction &= kPhaseMask;
-
-        // time to fetch another sample
-        while (indexIncrement--) {
-
-            inputIndex++;
-            if (inputIndex == mBuffer.frameCount) {
-                inputIndex = 0;
-                provider->releaseBuffer(&mBuffer);
-                mBuffer.frameCount = inFrameCount;
-                provider->getNextBuffer(&mBuffer);
-                if (mBuffer.raw == NULL)
-                    goto save_state;  // ugly, but efficient
-                in = mBuffer.i16;
-                // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
-            }
-
-            // advance sample state
-            advance(&left, in[inputIndex*2]);
-            advance(&right, in[inputIndex*2+1]);
-        }
-    }
-
-save_state:
-    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
-    mInputIndex = inputIndex;
-    mPhaseFraction = phaseFraction;
-}
-
-void AudioResamplerCubic::resampleMono16(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider) {
-
-    int32_t vl = mVolume[0];
-    int32_t vr = mVolume[1];
-
-    size_t inputIndex = mInputIndex;
-    uint32_t phaseFraction = mPhaseFraction;
-    uint32_t phaseIncrement = mPhaseIncrement;
-    size_t outputIndex = 0;
-    size_t outputSampleCount = outFrameCount * 2;
-    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
-    // fetch first buffer
-    if (mBuffer.frameCount == 0) {
-        mBuffer.frameCount = inFrameCount;
-        provider->getNextBuffer(&mBuffer);
-        if (mBuffer.raw == NULL)
-            return;
-        // LOGW("New buffer: offset=%p, frames=%d\n", mBuffer.raw, mBuffer.frameCount);
-    }
-    int16_t *in = mBuffer.i16;
-
-    while (outputIndex < outputSampleCount) {
-        int32_t sample;
-        int32_t x;
-
-        // calculate output sample
-        x = phaseFraction >> kPreInterpShift;
-        sample = interp(&left, x);
-        out[outputIndex++] += vl * sample;
-        out[outputIndex++] += vr * sample;
-
-        // increment phase
-        phaseFraction += phaseIncrement;
-        uint32_t indexIncrement = (phaseFraction >> kNumPhaseBits);
-        phaseFraction &= kPhaseMask;
-
-        // time to fetch another sample
-        while (indexIncrement--) {
-
-            inputIndex++;
-            if (inputIndex == mBuffer.frameCount) {
-                inputIndex = 0;
-                provider->releaseBuffer(&mBuffer);
-                mBuffer.frameCount = inFrameCount;
-                provider->getNextBuffer(&mBuffer);
-                if (mBuffer.raw == NULL)
-                    goto save_state;  // ugly, but efficient
-                // LOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
-                in = mBuffer.i16;
-            }
-
-            // advance sample state
-            advance(&left, in[inputIndex]);
-        }
-    }
-
-save_state:
-    // LOGW("Done: index=%d, fraction=%u", inputIndex, phaseFraction);
-    mInputIndex = inputIndex;
-    mPhaseFraction = phaseFraction;
-}
-
-// ----------------------------------------------------------------------------
-}
-; // namespace android
-
diff --git a/libs/audioflinger/AudioResamplerCubic.h b/libs/audioflinger/AudioResamplerCubic.h
deleted file mode 100644
index b72b62a..0000000
--- a/libs/audioflinger/AudioResamplerCubic.h
+++ /dev/null
@@ -1,68 +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_AUDIO_RESAMPLER_CUBIC_H
-#define ANDROID_AUDIO_RESAMPLER_CUBIC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-
-#include "AudioResampler.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-class AudioResamplerCubic : public AudioResampler {
-public:
-    AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
-        AudioResampler(bitDepth, inChannelCount, sampleRate) {
-    }
-    virtual void resample(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-private:
-    // number of bits used in interpolation multiply - 14 bits avoids overflow
-    static const int kNumInterpBits = 14;
-
-    // bits to shift the phase fraction down to avoid overflow
-    static const int kPreInterpShift = kNumPhaseBits - kNumInterpBits;
-    typedef struct {
-        int32_t a, b, c, y0, y1, y2, y3;
-    } state;
-    void init();
-    void resampleMono16(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-    void resampleStereo16(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-    static inline int32_t interp(state* p, int32_t x) {
-        return (((((p->a * x >> 14) + p->b) * x >> 14) + p->c) * x >> 14) + p->y1;
-    }
-    static inline void advance(state* p, int16_t in) {
-        p->y0 = p->y1;
-        p->y1 = p->y2;
-        p->y2 = p->y3;
-        p->y3 = in;
-        p->a = (3 * (p->y1 - p->y2) - p->y0 + p->y3) >> 1;            
-        p->b = (p->y2 << 1) + p->y0 - (((5 * p->y1 + p->y3)) >> 1);
-        p->c = (p->y2 - p->y0) >> 1;
-    }
-    state left, right;
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif /*ANDROID_AUDIO_RESAMPLER_CUBIC_H*/
diff --git a/libs/audioflinger/AudioResamplerSinc.cpp b/libs/audioflinger/AudioResamplerSinc.cpp
deleted file mode 100644
index 9e5e254..0000000
--- a/libs/audioflinger/AudioResamplerSinc.cpp
+++ /dev/null
@@ -1,358 +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 <string.h>
-#include "AudioResamplerSinc.h"
-
-namespace android {
-// ----------------------------------------------------------------------------
-
-
-/*
- * These coeficients are computed with the "fir" utility found in
- * tools/resampler_tools
- * TODO: A good optimization would be to transpose this matrix, to take
- * better advantage of the data-cache.
- */
-const int32_t AudioResamplerSinc::mFirCoefsUp[] = {
-        0x7fffffff, 0x7f15d078, 0x7c5e0da6, 0x77ecd867, 0x71e2e251, 0x6a6c304a, 0x61be7269, 0x58170412, 0x4db8ab05, 0x42e92ea6, 0x37eee214, 0x2d0e3bb1, 0x22879366, 0x18951e95, 0x0f693d0d, 0x072d2621,
-        0x00000000, 0xf9f66655, 0xf51a5fd7, 0xf16bbd84, 0xeee0d9ac, 0xed67a922, 0xece70de6, 0xed405897, 0xee50e505, 0xeff3be30, 0xf203370f, 0xf45a6741, 0xf6d67d53, 0xf957db66, 0xfbc2f647, 0xfe00f2b9,
-        0x00000000, 0x01b37218, 0x0313a0c6, 0x041d930d, 0x04d28057, 0x053731b0, 0x05534dff, 0x05309bfd, 0x04da440d, 0x045c1aee, 0x03c1fcdd, 0x03173ef5, 0x02663ae8, 0x01b7f736, 0x0113ec79, 0x007fe6a9,
-        0x00000000, 0xff96b229, 0xff44f99f, 0xff0a86be, 0xfee5f803, 0xfed518fd, 0xfed521fd, 0xfee2f4fd, 0xfefb54f8, 0xff1b159b, 0xff3f4203, 0xff6539e0, 0xff8ac502, 0xffae1ddd, 0xffcdf3f9, 0xffe96798,
-        0x00000000, 0x00119de6, 0x001e6b7e, 0x0026cb7a, 0x002b4830, 0x002c83d6, 0x002b2a82, 0x0027e67a, 0x002356f9, 0x001e098e, 0x001875e4, 0x0012fbbe, 0x000de2d1, 0x00095c10, 0x00058414, 0x00026636,
-        0x00000000, 0xfffe44a9, 0xfffd206d, 0xfffc7b7f, 0xfffc3c8f, 0xfffc4ac2, 0xfffc8f2b, 0xfffcf5c4, 0xfffd6df3, 0xfffdeab2, 0xfffe6275, 0xfffececf, 0xffff2c07, 0xffff788c, 0xffffb471, 0xffffe0f2,
-        0x00000000, 0x000013e6, 0x00001f03, 0x00002396, 0x00002399, 0x000020b6, 0x00001c3c, 0x00001722, 0x00001216, 0x00000d81, 0x0000099c, 0x0000067c, 0x00000419, 0x0000025f, 0x00000131, 0x00000070,
-        0x00000000, 0xffffffc7, 0xffffffb3, 0xffffffb3, 0xffffffbe, 0xffffffcd, 0xffffffdb, 0xffffffe7, 0xfffffff0, 0xfffffff7, 0xfffffffb, 0xfffffffe, 0xffffffff, 0x00000000, 0x00000000, 0x00000000,
-        0x00000000 // this one is needed for lerping the last coefficient
-};
-
-/*
- * These coefficients are optimized for 48KHz -> 44.1KHz (stop-band at 22.050KHz)
- * It's possible to use the above coefficient for any down-sampling
- * at the expense of a slower processing loop (we can interpolate
- * these coefficient from the above by "Stretching" them in time).
- */
-const int32_t AudioResamplerSinc::mFirCoefsDown[] = {
-        0x7fffffff, 0x7f55e46d, 0x7d5b4c60, 0x7a1b4b98, 0x75a7fb14, 0x7019f0bd, 0x698f875a, 0x622bfd59, 0x5a167256, 0x5178cc54, 0x487e8e6c, 0x3f53aae8, 0x36235ad4, 0x2d17047b, 0x245539ab, 0x1c00d540,
-        0x14383e57, 0x0d14d5ca, 0x06aa910b, 0x0107c38b, 0xfc351654, 0xf835abae, 0xf5076b45, 0xf2a37202, 0xf0fe9faa, 0xf00a3bbd, 0xefb4aa81, 0xefea2b05, 0xf0959716, 0xf1a11e83, 0xf2f6f7a0, 0xf481fff4,
-        0xf62e48ce, 0xf7e98ca5, 0xf9a38b4c, 0xfb4e4bfa, 0xfcde456f, 0xfe4a6d30, 0xff8c2fdf, 0x009f5555, 0x0181d393, 0x0233940f, 0x02b62f06, 0x030ca07d, 0x033afa62, 0x03461725, 0x03334f83, 0x030835fa,
-        0x02ca59cc, 0x027f12d1, 0x022b570d, 0x01d39a49, 0x017bb78f, 0x0126e414, 0x00d7aaaf, 0x008feec7, 0x0050f584, 0x001b73e3, 0xffefa063, 0xffcd46ed, 0xffb3ddcd, 0xffa29aaa, 0xff988691, 0xff949066,
-        0xff959d24, 0xff9a959e, 0xffa27195, 0xffac4011, 0xffb72d2b, 0xffc28569, 0xffcdb706, 0xffd85171, 0xffe20364, 0xffea97e9, 0xfff1f2b2, 0xfff80c06, 0xfffcec92, 0x0000a955, 0x00035fd8, 0x000532cf,
-        0x00064735, 0x0006c1f9, 0x0006c62d, 0x000673ba, 0x0005e68f, 0x00053630, 0x000475a3, 0x0003b397, 0x0002fac1, 0x00025257, 0x0001be9e, 0x0001417a, 0x0000dafd, 0x000089eb, 0x00004c28, 0x00001f1d,
-        0x00000000, 0xffffec10, 0xffffe0be, 0xffffdbc5, 0xffffdb39, 0xffffdd8b, 0xffffe182, 0xffffe638, 0xffffeb0a, 0xffffef8f, 0xfffff38b, 0xfffff6e3, 0xfffff993, 0xfffffba6, 0xfffffd30, 0xfffffe4a,
-        0xffffff09, 0xffffff85, 0xffffffd1, 0xfffffffb, 0x0000000f, 0x00000016, 0x00000015, 0x00000012, 0x0000000d, 0x00000009, 0x00000006, 0x00000003, 0x00000002, 0x00000001, 0x00000000, 0x00000000,
-        0x00000000 // this one is needed for lerping the last coefficient
-};
-
-// ----------------------------------------------------------------------------
-
-static inline
-int32_t mulRL(int left, int32_t in, uint32_t vRL)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    if (left) {
-        asm( "smultb %[out], %[in], %[vRL] \n"
-             : [out]"=r"(out)
-             : [in]"%r"(in), [vRL]"r"(vRL)
-             : );
-    } else {
-        asm( "smultt %[out], %[in], %[vRL] \n"
-             : [out]"=r"(out)
-             : [in]"%r"(in), [vRL]"r"(vRL)
-             : );
-    }
-    return out;
-#else
-    if (left) {
-        return int16_t(in>>16) * int16_t(vRL&0xFFFF);
-    } else {
-        return int16_t(in>>16) * int16_t(vRL>>16);
-    }
-#endif
-}
-
-static inline
-int32_t mulAdd(int16_t in, int32_t v, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    asm( "smlawb %[out], %[v], %[in], %[a] \n"
-         : [out]"=r"(out)
-         : [in]"%r"(in), [v]"r"(v), [a]"r"(a)
-         : );
-    return out;
-#else
-    return a + in * (v>>16);
-    // improved precision
-    // return a + in * (v>>16) + ((in * (v & 0xffff)) >> 16);
-#endif
-}
-
-static inline
-int32_t mulAddRL(int left, uint32_t inRL, int32_t v, int32_t a)
-{
-#if defined(__arm__) && !defined(__thumb__)
-    int32_t out;
-    if (left) {
-        asm( "smlawb %[out], %[v], %[inRL], %[a] \n"
-             : [out]"=r"(out)
-             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
-             : );
-    } else {
-        asm( "smlawt %[out], %[v], %[inRL], %[a] \n"
-             : [out]"=r"(out)
-             : [inRL]"%r"(inRL), [v]"r"(v), [a]"r"(a)
-             : );
-    }
-    return out;
-#else
-    if (left) {
-        return a + (int16_t(inRL&0xFFFF) * (v>>16));
-        //improved precision
-        // return a + (int16_t(inRL&0xFFFF) * (v>>16)) + ((int16_t(inRL&0xFFFF) * (v & 0xffff)) >> 16);
-    } else {
-        return a + (int16_t(inRL>>16) * (v>>16));
-    }
-#endif
-}
-
-// ----------------------------------------------------------------------------
-
-AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
-        int inChannelCount, int32_t sampleRate)
-    : AudioResampler(bitDepth, inChannelCount, sampleRate),
-    mState(0)
-{
-    /*
-     * Layout of the state buffer for 32 tap:
-     *
-     * "present" sample            beginning of 2nd buffer
-     *                 v                v
-     *  0              01               2              23              3
-     *  0              F0               0              F0              F
-     * [pppppppppppppppInnnnnnnnnnnnnnnnpppppppppppppppInnnnnnnnnnnnnnnn]
-     *                 ^               ^ head
-     *
-     * p = past samples, convoluted with the (p)ositive side of sinc()
-     * n = future samples, convoluted with the (n)egative side of sinc()
-     * r = extra space for implementing the ring buffer
-     *
-     */
-
-    const size_t numCoefs = 2*halfNumCoefs;
-    const size_t stateSize = numCoefs * inChannelCount * 2;
-    mState = new int16_t[stateSize];
-    memset(mState, 0, sizeof(int16_t)*stateSize);
-    mImpulse = mState + (halfNumCoefs-1)*inChannelCount;
-    mRingFull = mImpulse + (numCoefs+1)*inChannelCount;
-}
-
-AudioResamplerSinc::~AudioResamplerSinc()
-{
-    delete [] mState;
-}
-
-void AudioResamplerSinc::init() {
-}
-
-void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider)
-{
-    mFirCoefs = (mInSampleRate <= mSampleRate) ? mFirCoefsUp : mFirCoefsDown;
-
-    // select the appropriate resampler
-    switch (mChannelCount) {
-    case 1:
-        resample<1>(out, outFrameCount, provider);
-        break;
-    case 2:
-        resample<2>(out, outFrameCount, provider);
-        break;
-    }
-}
-
-
-template<int CHANNELS>
-void AudioResamplerSinc::resample(int32_t* out, size_t outFrameCount,
-        AudioBufferProvider* provider)
-{
-    int16_t* impulse = mImpulse;
-    uint32_t vRL = mVolumeRL;
-    size_t inputIndex = mInputIndex;
-    uint32_t phaseFraction = mPhaseFraction;
-    uint32_t phaseIncrement = mPhaseIncrement;
-    size_t outputIndex = 0;
-    size_t outputSampleCount = outFrameCount * 2;
-    size_t inFrameCount = (outFrameCount*mInSampleRate)/mSampleRate;
-
-    AudioBufferProvider::Buffer& buffer(mBuffer);
-    while (outputIndex < outputSampleCount) {
-        // buffer is empty, fetch a new one
-        while (buffer.frameCount == 0) {
-            buffer.frameCount = inFrameCount;
-            provider->getNextBuffer(&buffer);
-            if (buffer.raw == NULL) {
-                goto resample_exit;
-            }
-            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
-            if (phaseIndex == 1) {
-                // read one frame
-                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
-            } else if (phaseIndex == 2) {
-                // read 2 frames
-                read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
-                inputIndex++;
-                if (inputIndex >= mBuffer.frameCount) {
-                    inputIndex -= mBuffer.frameCount;
-                    provider->releaseBuffer(&buffer);
-                } else {
-                    read<CHANNELS>(impulse, phaseFraction, buffer.i16, inputIndex);
-                }
-           }
-        }
-        int16_t *in = buffer.i16;
-        const size_t frameCount = buffer.frameCount;
-
-        // Always read-in the first samples from the input buffer
-        int16_t* head = impulse + halfNumCoefs*CHANNELS;
-        head[0] = in[inputIndex*CHANNELS + 0];
-        if (CHANNELS == 2)
-            head[1] = in[inputIndex*CHANNELS + 1];
-
-        // handle boundary case
-        int32_t l, r;
-        while (outputIndex < outputSampleCount) {
-            filterCoefficient<CHANNELS>(l, r, phaseFraction, impulse);
-            out[outputIndex++] += 2 * mulRL(1, l, vRL);
-            out[outputIndex++] += 2 * mulRL(0, r, vRL);
-
-            phaseFraction += phaseIncrement;
-            const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
-            if (phaseIndex == 1) {
-                inputIndex++;
-                if (inputIndex >= frameCount)
-                    break;  // need a new buffer
-                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
-            } else if(phaseIndex == 2) {    // maximum value
-                inputIndex++;
-                if (inputIndex >= frameCount)
-                    break;  // 0 frame available, 2 frames needed
-                // read first frame
-                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
-                inputIndex++;
-                if (inputIndex >= frameCount)
-                    break;  // 0 frame available, 1 frame needed
-                // read second frame
-                read<CHANNELS>(impulse, phaseFraction, in, inputIndex);
-            }
-        }
-
-        // if done with buffer, save samples
-        if (inputIndex >= frameCount) {
-            inputIndex -= frameCount;
-            provider->releaseBuffer(&buffer);
-        }
-    }
-
-resample_exit:
-    mImpulse = impulse;
-    mInputIndex = inputIndex;
-    mPhaseFraction = phaseFraction;
-}
-
-template<int CHANNELS>
-/***
-* read()
-*
-* This function reads only one frame from input buffer and writes it in
-* state buffer
-*
-**/
-void AudioResamplerSinc::read(
-        int16_t*& impulse, uint32_t& phaseFraction,
-        int16_t const* in, size_t inputIndex)
-{
-    const uint32_t phaseIndex = phaseFraction >> kNumPhaseBits;
-    impulse += CHANNELS;
-    phaseFraction -= 1LU<<kNumPhaseBits;
-    if (impulse >= mRingFull) {
-        const size_t stateSize = (halfNumCoefs*2)*CHANNELS;
-        memcpy(mState, mState+stateSize, sizeof(int16_t)*stateSize);
-        impulse -= stateSize;
-    }
-    int16_t* head = impulse + halfNumCoefs*CHANNELS;
-    head[0] = in[inputIndex*CHANNELS + 0];
-    if (CHANNELS == 2)
-        head[1] = in[inputIndex*CHANNELS + 1];
-}
-
-template<int CHANNELS>
-void AudioResamplerSinc::filterCoefficient(
-        int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples)
-{
-    // compute the index of the coefficient on the positive side and
-    // negative side
-    uint32_t indexP = (phase & cMask) >> cShift;
-    uint16_t lerpP  = (phase & pMask) >> pShift;
-    uint32_t indexN = (-phase & cMask) >> cShift;
-    uint16_t lerpN  = (-phase & pMask) >> pShift;
-    if ((indexP == 0) && (lerpP == 0)) {
-        indexN = cMask >> cShift;
-        lerpN = pMask >> pShift;
-    }
-
-    l = 0;
-    r = 0;
-    int32_t const* coefs = mFirCoefs;
-    int16_t const *sP = samples;
-    int16_t const *sN = samples+CHANNELS;
-    for (unsigned int i=0 ; i<halfNumCoefs/4 ; i++) {
-        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
-        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
-        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
-        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
-        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
-        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
-        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
-        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
-        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
-        interpolate<CHANNELS>(l, r, coefs+indexP, lerpP, sP);
-        interpolate<CHANNELS>(l, r, coefs+indexN, lerpN, sN);
-        sP -= CHANNELS; sN += CHANNELS; coefs += 1<<coefsBits;
-    }
-}
-
-template<int CHANNELS>
-void AudioResamplerSinc::interpolate(
-        int32_t& l, int32_t& r,
-        int32_t const* coefs, int16_t lerp, int16_t const* samples)
-{
-    int32_t c0 = coefs[0];
-    int32_t c1 = coefs[1];
-    int32_t sinc = mulAdd(lerp, (c1-c0)<<1, c0);
-    if (CHANNELS == 2) {
-        uint32_t rl = *reinterpret_cast<uint32_t const*>(samples);
-        l = mulAddRL(1, rl, sinc, l);
-        r = mulAddRL(0, rl, sinc, r);
-    } else {
-        r = l = mulAdd(samples[0], sinc, l);
-    }
-}
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
diff --git a/libs/audioflinger/AudioResamplerSinc.h b/libs/audioflinger/AudioResamplerSinc.h
deleted file mode 100644
index e6cb90b..0000000
--- a/libs/audioflinger/AudioResamplerSinc.h
+++ /dev/null
@@ -1,88 +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_AUDIO_RESAMPLER_SINC_H
-#define ANDROID_AUDIO_RESAMPLER_SINC_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <cutils/log.h>
-
-#include "AudioResampler.h"
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class AudioResamplerSinc : public AudioResampler {
-public:
-    AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate);
-
-    ~AudioResamplerSinc();
-
-    virtual void resample(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-private:
-    void init();
-
-    template<int CHANNELS>
-    void resample(int32_t* out, size_t outFrameCount,
-            AudioBufferProvider* provider);
-
-    template<int CHANNELS>
-    inline void filterCoefficient(
-            int32_t& l, int32_t& r, uint32_t phase, int16_t const *samples);
-
-    template<int CHANNELS>
-    inline void interpolate(
-            int32_t& l, int32_t& r,
-            int32_t const* coefs, int16_t lerp, int16_t const* samples);
-
-    template<int CHANNELS>
-    inline void read(int16_t*& impulse, uint32_t& phaseFraction,
-            int16_t const* in, size_t inputIndex);
-
-    int16_t *mState;
-    int16_t *mImpulse;
-    int16_t *mRingFull;
-
-    int32_t const * mFirCoefs;
-    static const int32_t mFirCoefsDown[];
-    static const int32_t mFirCoefsUp[];
-
-    // ----------------------------------------------------------------------------
-    static const int32_t RESAMPLE_FIR_NUM_COEF       = 8;
-    static const int32_t RESAMPLE_FIR_LERP_INT_BITS  = 4;
-
-    // we have 16 coefs samples per zero-crossing
-    static const int coefsBits = RESAMPLE_FIR_LERP_INT_BITS;        // 4
-    static const int cShift = kNumPhaseBits - coefsBits;            // 26
-    static const uint32_t cMask  = ((1<<coefsBits)-1) << cShift;    // 0xf<<26 = 3c00 0000
-
-    // and we use 15 bits to interpolate between these samples
-    // this cannot change because the mul below rely on it.
-    static const int pLerpBits = 15;
-    static const int pShift = kNumPhaseBits - coefsBits - pLerpBits;    // 11
-    static const uint32_t pMask  = ((1<<pLerpBits)-1) << pShift;    // 0x7fff << 11
-
-    // number of zero-crossing on each side
-    static const unsigned int halfNumCoefs = RESAMPLE_FIR_NUM_COEF;
-};
-
-// ----------------------------------------------------------------------------
-}; // namespace android
-
-#endif /*ANDROID_AUDIO_RESAMPLER_SINC_H*/
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 0016503..13c58f0 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);
@@ -497,12 +517,26 @@
     }
     
     if ((flags & TF_ONE_WAY) == 0) {
+        #if 0
+        if (code == 4) { // relayout
+            LOGI(">>>>>> CALLING transaction 4");
+        } else {
+            LOGI(">>>>>> CALLING transaction %d", code);
+        }
+        #endif
         if (reply) {
             err = waitForResponse(reply);
         } else {
             Parcel fakeReply;
             err = waitForResponse(&fakeReply);
         }
+        #if 0
+        if (code == 4) { // relayout
+            LOGI("<<<<<< RETURNING transaction 4");
+        } else {
+            LOGI("<<<<<< RETURNING transaction %d", code);
+        }
+        #endif
         
         IF_LOG_TRANSACTIONS() {
             TextOutput::Bundle _b(alog);
@@ -588,7 +622,10 @@
 }
 
 IPCThreadState::IPCThreadState()
-    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
+    : mProcess(ProcessState::self()),
+      mMyThreadId(androidGetTid()),
+      mStrictModePolicy(0),
+      mLastTransactionBinderFlags(0)
 {
     pthread_setspecific(gTLS, this);
     clearCaller();
@@ -972,11 +1009,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..f935524
--- /dev/null
+++ b/libs/gui/SensorEventQueue.cpp
@@ -0,0 +1,149 @@
+/*
+ * 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/Looper.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]));
+    LOGE_IF(size<0 && size!=-EAGAIN,
+            "SensorChannel::read error (%s)", strerror(-size));
+    if (size >= 0) {
+        if (size % sizeof(events[0])) {
+            // partial read!!! should never happen.
+            LOGE("SensorEventQueue partial read (event-size=%u, read=%d)",
+                    sizeof(events[0]), int(size));
+            return -EINVAL;
+        }
+        // returns number of events read
+        size /= sizeof(events[0]);
+    }
+    return size;
+}
+
+sp<Looper> SensorEventQueue::getLooper() const
+{
+    Mutex::Autolock _l(mLock);
+    if (mLooper == 0) {
+        mLooper = new Looper(true);
+        mLooper->addFd(getFd(), getFd(), ALOOPER_EVENT_INPUT, NULL, NULL);
+    }
+    return mLooper;
+}
+
+status_t SensorEventQueue::waitForEvent() const
+{
+    const int fd = getFd();
+    sp<Looper> looper(getLooper());
+
+    int32_t result;
+    do {
+        result = looper->pollOnce(-1);
+        if (result == ALOOPER_EVENT_ERROR) {
+            LOGE("SensorChannel::waitForEvent error (errno=%d)", errno);
+            result = -EPIPE; // unknown error, so we make up one
+            break;
+        }
+    } while (result != fd);
+
+    return  (result == fd) ? status_t(NO_ERROR) : result;
+}
+
+status_t SensorEventQueue::wake() const
+{
+    sp<Looper> looper(getLooper());
+    looper->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/Android.mk b/libs/surfaceflinger/Android.mk
deleted file mode 100644
index 86eb78d..0000000
--- a/libs/surfaceflinger/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= \
-    clz.cpp.arm \
-    DisplayHardware/DisplayHardware.cpp \
-    DisplayHardware/DisplayHardwareBase.cpp \
-    BlurFilter.cpp.arm \
-    Layer.cpp \
-    LayerBase.cpp \
-    LayerBuffer.cpp \
-    LayerBlur.cpp \
-    LayerDim.cpp \
-    MessageQueue.cpp \
-    SurfaceFlinger.cpp \
-    Tokenizer.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
-endif
-
-# need "-lrt" on Linux simulator to pick up clock_gettime
-ifeq ($(TARGET_SIMULATOR),true)
-	ifeq ($(HOST_OS),linux)
-		LOCAL_LDLIBS += -lrt -lpthread
-	endif
-endif
-
-LOCAL_SHARED_LIBRARIES := \
-	libcutils \
-	libpixelflinger \
-	libhardware \
-	libutils \
-	libEGL \
-	libGLESv1_CM \
-	libbinder \
-	libui \
-	libsurfaceflinger_client
-
-LOCAL_C_INCLUDES := \
-	$(call include-path-for, corecg graphics)
-
-LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc
-
-LOCAL_MODULE:= libsurfaceflinger
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/surfaceflinger/Barrier.h b/libs/surfaceflinger/Barrier.h
deleted file mode 100644
index e2bcf6a..0000000
--- a/libs/surfaceflinger/Barrier.h
+++ /dev/null
@@ -1,59 +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_BARRIER_H
-#define ANDROID_BARRIER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <utils/threads.h>
-
-namespace android {
-
-class Barrier
-{
-public:
-    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();
-    }
-    void close() {
-        Mutex::Autolock _l(lock);
-        state = CLOSED;
-    }
-    void wait() const {
-        Mutex::Autolock _l(lock);
-        while (state == CLOSED) {
-            cv.wait(lock);
-        }
-    }
-private:
-    enum { OPENED, CLOSED };
-    mutable     Mutex       lock;
-    mutable     Condition   cv;
-    volatile    int         state;
-};
-
-}; // namespace android
-
-#endif // ANDROID_BARRIER_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
deleted file mode 100644
index ea68352..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp
+++ /dev/null
@@ -1,364 +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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-
-#include <cutils/properties.h>
-
-#include <utils/RefBase.h>
-#include <utils/Log.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/FramebufferNativeWindow.h>
-#include <ui/EGLUtils.h>
-
-#include <GLES/gl.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "DisplayHardware/DisplayHardware.h"
-
-#include <hardware/copybit.h>
-#include <hardware/overlay.h>
-#include <hardware/gralloc.h>
-
-using namespace android;
-
-
-static __attribute__((noinline))
-void checkGLErrors()
-{
-    do {
-        // there could be more than one error flag
-        GLenum error = glGetError();
-        if (error == GL_NO_ERROR)
-            break;
-        LOGE("GL error 0x%04x", int(error));
-    } while(true);
-}
-
-static __attribute__((noinline))
-void checkEGLErrors(const char* token)
-{
-    EGLint error = eglGetError();
-    if (error && error != EGL_SUCCESS) {
-        LOGE("%s: EGL error 0x%04x (%s)",
-                token, int(error), EGLUtils::strerror(error));
-    }
-}
-
-/*
- * Initialize the display to the specified values.
- *
- */
-
-DisplayHardware::DisplayHardware(
-        const sp<SurfaceFlinger>& flinger,
-        uint32_t dpy)
-    : DisplayHardwareBase(flinger, dpy)
-{
-    init(dpy);
-}
-
-DisplayHardware::~DisplayHardware()
-{
-    fini();
-}
-
-float DisplayHardware::getDpiX() const          { return mDpiX; }
-float DisplayHardware::getDpiY() const          { return mDpiY; }
-float DisplayHardware::getDensity() const       { return mDensity; }
-float DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
-int DisplayHardware::getWidth() const           { return mWidth; }
-int DisplayHardware::getHeight() const          { return mHeight; }
-PixelFormat DisplayHardware::getFormat() const  { return mFormat; }
-uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
-uint32_t DisplayHardware::getMaxViewportDims() const { return mMaxViewportDims; }
-
-void DisplayHardware::init(uint32_t dpy)
-{
-    mNativeWindow = new FramebufferNativeWindow();
-    framebuffer_device_t const * fbDev = mNativeWindow->getDevice();
-
-    mOverlayEngine = NULL;
-    hw_module_t const* module;
-    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
-        overlay_control_open(module, &mOverlayEngine);
-    }
-
-    // initialize EGL
-    EGLint attribs[] = {
-            EGL_SURFACE_TYPE,   EGL_WINDOW_BIT,
-            EGL_NONE,           0,
-            EGL_NONE
-    };
-
-    // debug: disable h/w rendering
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get("debug.sf.hw", property, NULL) > 0) {
-        if (atoi(property) == 0) {
-            LOGW("H/W composition disabled");
-            attribs[2] = EGL_CONFIG_CAVEAT;
-            attribs[3] = EGL_SLOW_CONFIG;
-        }
-    }
-
-    EGLint w, h, dummy;
-    EGLint numConfigs=0;
-    EGLSurface surface;
-    EGLContext context;
-    mFlags = CACHED_BUFFERS;
-
-    // TODO: all the extensions below should be queried through
-    // eglGetProcAddress().
-
-    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    eglInitialize(display, NULL, NULL);
-    eglGetConfigs(display, NULL, 0, &numConfigs);
-
-    EGLConfig config;
-    status_t err = EGLUtils::selectConfigForNativeWindow(
-            display, attribs, mNativeWindow.get(), &config);
-    LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
-    
-    EGLint r,g,b,a;
-    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
-    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
-    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;
-    }
-    
-    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
-        if (dummy == EGL_SLOW_CONFIG)
-            mFlags |= SLOW_CONFIG;
-    }
-
-    /*
-     * Create our main surface
-     */
-
-    surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL);
-
-    if (mFlags & PARTIAL_UPDATES) {
-        // if we have partial updates, we definitely don't need to
-        // preserve the backbuffer, which may be costly.
-        eglSurfaceAttrib(display, surface,
-                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
-    }
-
-    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
-        if (dummy == EGL_BUFFER_PRESERVED) {
-            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.
-     */
-    if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) {
-        if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
-            LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
-            strcpy(property, "160");
-        }
-    } else {
-        /* for the emulator case, reset the dpi values too */
-        mDpiX = mDpiY = atoi(property);
-    }
-    mDensity = atoi(property) * (1.0f/160.0f);
-
-
-    /*
-     * Create our OpenGL ES context
-     */
-    
-    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;
-}
-
-/*
- * Clean up.  Throw out our local state.
- *
- * (It's entirely possible we'll never get here, since this is meant
- * for real hardware, which doesn't restart.)
- */
-
-void DisplayHardware::fini()
-{
-    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-    eglTerminate(mDisplay);
-    overlay_control_close(mOverlayEngine);
-}
-
-void DisplayHardware::releaseScreen() const
-{
-    DisplayHardwareBase::releaseScreen();
-}
-
-void DisplayHardware::acquireScreen() const
-{
-    DisplayHardwareBase::acquireScreen();
-}
-
-uint32_t DisplayHardware::getPageFlipCount() const {
-    return mPageFlipCount;
-}
-
-status_t DisplayHardware::compositionComplete() const {
-    return mNativeWindow->compositionComplete();
-}
-
-void DisplayHardware::flip(const Region& dirty) const
-{
-    checkGLErrors();
-
-    EGLDisplay dpy = mDisplay;
-    EGLSurface surface = mSurface;
-
-#ifdef EGL_ANDROID_swap_rectangle    
-    if (mFlags & SWAP_RECTANGLE) {
-        const Region newDirty(dirty.intersect(bounds()));
-        const Rect b(newDirty.getBounds());
-        eglSetSwapRectangleANDROID(dpy, surface,
-                b.left, b.top, b.width(), b.height());
-    } 
-#endif
-    
-    if (mFlags & PARTIAL_UPDATES) {
-        mNativeWindow->setUpdateRectangle(dirty.getBounds());
-    }
-    
-    mPageFlipCount++;
-    eglSwapBuffers(dpy, surface);
-    checkEGLErrors("eglSwapBuffers");
-
-    // for debugging
-    //glClearColor(1,0,0,0);
-    //glClear(GL_COLOR_BUFFER_BIT);
-}
-
-uint32_t DisplayHardware::getFlags() const
-{
-    return mFlags;
-}
-
-void DisplayHardware::makeCurrent() const
-{
-    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
-}
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h b/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
deleted file mode 100644
index df046af..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.h
+++ /dev/null
@@ -1,118 +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_DISPLAY_HARDWARE_H
-#define ANDROID_DISPLAY_HARDWARE_H
-
-#include <stdlib.h>
-
-#include <ui/PixelFormat.h>
-#include <ui/Region.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "DisplayHardware/DisplayHardwareBase.h"
-
-struct overlay_control_device_t;
-struct framebuffer_device_t;
-struct copybit_image_t;
-
-namespace android {
-
-class FramebufferNativeWindow;
-
-class DisplayHardware : public DisplayHardwareBase
-{
-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
-    };
-
-    DisplayHardware(
-            const sp<SurfaceFlinger>& flinger,
-            uint32_t displayIndex);
-
-    ~DisplayHardware();
-
-    void releaseScreen() const;
-    void acquireScreen() const;
-
-    // Flip the front and back buffers if the back buffer is "dirty".  Might
-    // be instantaneous, might involve copying the frame buffer around.
-    void flip(const Region& dirty) const;
-
-    float       getDpiX() const;
-    float       getDpiY() const;
-    float       getRefreshRate() const;
-    float       getDensity() const;
-    int         getWidth() const;
-    int         getHeight() const;
-    PixelFormat getFormat() const;
-    uint32_t    getFlags() const;
-    void        makeCurrent() const;
-    uint32_t    getMaxTextureSize() const;
-    uint32_t    getMaxViewportDims() const;
-
-    uint32_t getPageFlipCount() const;
-    EGLDisplay getEGLDisplay() const { return mDisplay; }
-    overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
-    
-    status_t compositionComplete() const;
-    
-    Rect bounds() const {
-        return Rect(mWidth, mHeight);
-    }
-
-private:
-    void init(uint32_t displayIndex) __attribute__((noinline));
-    void fini() __attribute__((noinline));
-
-    EGLDisplay      mDisplay;
-    EGLSurface      mSurface;
-    EGLContext      mContext;
-    EGLConfig       mConfig;
-    float           mDpiX;
-    float           mDpiY;
-    float           mRefreshRate;
-    float           mDensity;
-    int             mWidth;
-    int             mHeight;
-    PixelFormat     mFormat;
-    uint32_t        mFlags;
-    mutable uint32_t mPageFlipCount;
-    GLint           mMaxViewportDims;
-    GLint           mMaxTextureSize;
-    
-    sp<FramebufferNativeWindow> mNativeWindow;
-    overlay_control_device_t* mOverlayEngine;
-};
-
-}; // namespace android
-
-#endif // ANDROID_DISPLAY_HARDWARE_H
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
deleted file mode 100644
index 1d09f84..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
+++ /dev/null
@@ -1,401 +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 <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/resource.h>
-
-#include <linux/unistd.h>
-
-#include <utils/Log.h>
-
-#include "DisplayHardware/DisplayHardwareBase.h"
-#include "SurfaceFlinger.h"
-
-// ----------------------------------------------------------------------------
-// the sim build doesn't have gettid
-
-#ifndef HAVE_GETTID
-# define gettid getpid
-#endif
-
-// ----------------------------------------------------------------------------
-namespace android {
-
-static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep";
-static char const * kWakeFileName = "/sys/power/wait_for_fb_wake";
-static char const * const kOldSleepFileName = "/sys/android_power/wait_for_fb_sleep";
-static char const * const kOldWakeFileName = "/sys/android_power/wait_for_fb_wake";
-
-// This dir exists if the framebuffer console is present, either built into
-// the kernel or loaded as a module.
-static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";
-
-// ----------------------------------------------------------------------------
-
-DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
-        const sp<SurfaceFlinger>& flinger)
-    : Thread(false), mFlinger(flinger) {
-}
-
-DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
-}
-
-// ----------------------------------------------------------------------------
-
-DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
-        const sp<SurfaceFlinger>& flinger)
-    : DisplayEventThreadBase(flinger)
-{
-}
-
-DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
-{
-}
-
-bool DisplayHardwareBase::DisplayEventThread::threadLoop()
-{
-    int err = 0;
-    char buf;
-    int fd;
-
-    fd = open(kSleepFileName, O_RDONLY, 0);
-    do {
-      err = read(fd, &buf, 1);
-    } while (err < 0 && errno == EINTR);
-    close(fd);
-    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
-    if (err >= 0) {
-        sp<SurfaceFlinger> flinger = mFlinger.promote();
-        LOGD("About to give-up screen, flinger = %p", flinger.get());
-        if (flinger != 0) {
-            mBarrier.close();
-            flinger->screenReleased(0);
-            mBarrier.wait();
-        }
-    }
-    fd = open(kWakeFileName, O_RDONLY, 0);
-    do {
-      err = read(fd, &buf, 1);
-    } while (err < 0 && errno == EINTR);
-    close(fd);
-    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
-    if (err >= 0) {
-        sp<SurfaceFlinger> flinger = mFlinger.promote();
-        LOGD("Screen about to return, flinger = %p", flinger.get());
-        if (flinger != 0)
-            flinger->screenAcquired(0);
-    }
-    return true;
-}
-
-status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
-{
-    mBarrier.open();
-    return NO_ERROR;
-}
-
-status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
-{
-    if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
-        if (access(kOldSleepFileName, R_OK) || access(kOldWakeFileName, R_OK)) {
-            LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
-            return NO_INIT;
-        }
-        kSleepFileName = kOldSleepFileName;
-        kWakeFileName = kOldWakeFileName;
-    }
-    return NO_ERROR;
-}
-
-status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
-{
-    return (((access(kSleepFileName, R_OK) == 0 &&
-            access(kWakeFileName, R_OK) == 0) ||
-            (access(kOldSleepFileName, R_OK) == 0 &&
-            access(kOldWakeFileName, R_OK) == 0)) &&
-            access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
-}
-
-// ----------------------------------------------------------------------------
-
-pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;
-
-DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
-        const sp<SurfaceFlinger>& flinger)
-    : DisplayEventThreadBase(flinger), consoleFd(-1)
-{   
-    sSignalCatcherPid = 0;
-
-    // create a new console
-    char const * const ttydev = "/dev/tty0";
-    int fd = open(ttydev, O_RDWR | O_SYNC);
-    if (fd<0) {
-        LOGE("Can't open %s", ttydev);
-        this->consoleFd = -errno;
-        return;
-    }
-
-    // to make sure that we are in text mode
-    int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
-    if (res<0) {
-        LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
-                fd, res, strerror(errno));
-    }
-    
-    // get the current console
-    struct vt_stat vs;
-    res = ioctl(fd, VT_GETSTATE, &vs);
-    if (res<0) {
-        LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
-                fd, res, strerror(errno));
-        this->consoleFd = -errno;
-        return;
-    }
-
-    // switch to console 7 (which is what X normaly uses)
-    int vtnum = 7;
-    do {
-        res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
-    } while(res < 0 && errno == EINTR);
-    if (res<0) {
-        LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
-                fd, errno, strerror(errno), vtnum);
-        this->consoleFd = -errno;
-        return;
-    }
-
-    do {
-        res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
-    } while(res < 0 && errno == EINTR);
-    if (res<0) {
-        LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
-                fd, res, errno, strerror(errno), vtnum);
-        this->consoleFd = -errno;
-        return;
-    }
-
-    // open the new console
-    close(fd);
-    fd = open(ttydev, O_RDWR | O_SYNC);
-    if (fd<0) {
-        LOGE("Can't open new console %s", ttydev);
-        this->consoleFd = -errno;
-        return;
-    }
-
-    /* disable console line buffer, echo, ... */
-    struct termios ttyarg;
-    ioctl(fd, TCGETS , &ttyarg);
-    ttyarg.c_iflag = 0;
-    ttyarg.c_lflag = 0;
-    ioctl(fd, TCSETS , &ttyarg);
-
-    // set up signals so we're notified when the console changes
-    // we can't use SIGUSR1 because it's used by the java-vm
-    vm.mode = VT_PROCESS;
-    vm.waitv = 0;
-    vm.relsig = SIGUSR2;
-    vm.acqsig = SIGUNUSED;
-    vm.frsig = 0;
-
-    struct sigaction act;
-    sigemptyset(&act.sa_mask);
-    act.sa_handler = sigHandler;
-    act.sa_flags = 0;
-    sigaction(vm.relsig, &act, NULL);
-
-    sigemptyset(&act.sa_mask);
-    act.sa_handler = sigHandler;
-    act.sa_flags = 0;
-    sigaction(vm.acqsig, &act, NULL);
-
-    sigset_t mask;
-    sigemptyset(&mask);
-    sigaddset(&mask, vm.relsig);
-    sigaddset(&mask, vm.acqsig);
-    sigprocmask(SIG_BLOCK, &mask, NULL);
-
-    // switch to graphic mode
-    res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
-    LOGW_IF(res<0,
-            "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
-
-    this->prev_vt_num = vs.v_active;
-    this->vt_num = vtnum;
-    this->consoleFd = fd;
-}
-
-DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
-{   
-    if (this->consoleFd >= 0) {
-        int fd = this->consoleFd;
-        int prev_vt_num = this->prev_vt_num;
-        int res;
-        ioctl(fd, KDSETMODE, (void*)KD_TEXT);
-        do {
-            res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
-        } while(res < 0 && errno == EINTR);
-        do {
-            res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
-        } while(res < 0 && errno == EINTR);
-        close(fd);    
-        char const * const ttydev = "/dev/tty0";
-        fd = open(ttydev, O_RDWR | O_SYNC);
-        ioctl(fd, VT_DISALLOCATE, 0);
-        close(fd);
-    }
-}
-
-status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
-{
-    if (this->consoleFd >= 0) {
-        sSignalCatcherPid = gettid();
-        
-        sigset_t mask;
-        sigemptyset(&mask);
-        sigaddset(&mask, vm.relsig);
-        sigaddset(&mask, vm.acqsig);
-        sigprocmask(SIG_BLOCK, &mask, NULL);
-
-        int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
-        if (res<0) {
-            LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
-                    this->consoleFd, errno, strerror(errno));
-        }
-        return NO_ERROR;
-    }
-    return this->consoleFd;
-}
-
-void DisplayHardwareBase::ConsoleManagerThread::requestExit()
-{
-    Thread::requestExit();
-    if (sSignalCatcherPid != 0) {
-        // wake the thread up
-        kill(sSignalCatcherPid, SIGINT);
-        // wait for it...
-    }
-}
-
-void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
-{
-    // resend the signal to our signal catcher thread
-    LOGW("received signal %d in thread %d, resending to %d",
-            sig, gettid(), sSignalCatcherPid);
-
-    // we absolutely need the delays below because without them
-    // our main thread never gets a chance to handle the signal.
-    usleep(10000);
-    kill(sSignalCatcherPid, sig);
-    usleep(10000);
-}
-
-status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
-{
-    int fd = this->consoleFd;
-    int err = ioctl(fd, VT_RELDISP, (void*)1);
-    LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
-        fd, errno, strerror(errno));
-    return (err<0) ? (-errno) : status_t(NO_ERROR);
-}
-
-bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
-{
-    sigset_t mask;
-    sigemptyset(&mask);
-    sigaddset(&mask, vm.relsig);
-    sigaddset(&mask, vm.acqsig);
-
-    int sig = 0;
-    sigwait(&mask, &sig);
-
-    if (sig == vm.relsig) {
-        sp<SurfaceFlinger> flinger = mFlinger.promote();
-        //LOGD("About to give-up screen, flinger = %p", flinger.get());
-        if (flinger != 0)
-            flinger->screenReleased(0);
-    } else if (sig == vm.acqsig) {
-        sp<SurfaceFlinger> flinger = mFlinger.promote();
-        //LOGD("Screen about to return, flinger = %p", flinger.get());
-        if (flinger != 0) 
-            flinger->screenAcquired(0);
-    }
-    
-    return true;
-}
-
-status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
-{
-    return consoleFd >= 0 ? NO_ERROR : NO_INIT;
-}
-
-// ----------------------------------------------------------------------------
-
-DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
-        uint32_t displayIndex) 
-    : mCanDraw(true)
-{
-    mDisplayEventThread = new DisplayEventThread(flinger);
-    if (mDisplayEventThread->initCheck() != NO_ERROR) {
-        // fall-back on the console
-        mDisplayEventThread = new ConsoleManagerThread(flinger);
-    }
-}
-
-DisplayHardwareBase::~DisplayHardwareBase()
-{
-    // request exit
-    mDisplayEventThread->requestExitAndWait();
-}
-
-
-bool DisplayHardwareBase::canDraw() const
-{
-    return mCanDraw;
-}
-
-void DisplayHardwareBase::releaseScreen() const
-{
-    status_t err = mDisplayEventThread->releaseScreen();
-    if (err >= 0) {
-        //LOGD("screen given-up");
-        mCanDraw = false;
-    }
-}
-
-void DisplayHardwareBase::acquireScreen() const
-{
-    status_t err = mDisplayEventThread->acquireScreen();
-    if (err >= 0) {
-        //LOGD("screen returned");
-        mCanDraw = true;
-    }
-}
-
-}; // namespace android
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
deleted file mode 100644
index 8369bb8..0000000
--- a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
+++ /dev/null
@@ -1,96 +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_DISPLAY_HARDWARE_BASE_H
-#define ANDROID_DISPLAY_HARDWARE_BASE_H
-
-#include <stdint.h>
-#include <utils/RefBase.h>
-#include <utils/threads.h>
-#include <linux/kd.h>
-#include <linux/vt.h>
-#include "Barrier.h"
-
-namespace android {
-
-class SurfaceFlinger; 
-
-class DisplayHardwareBase
-{
-public:
-                DisplayHardwareBase(
-                        const sp<SurfaceFlinger>& flinger,
-                        uint32_t displayIndex);
-
-                ~DisplayHardwareBase();
-
-    // console managment
-    void releaseScreen() const;
-    void acquireScreen() const;
-    bool canDraw() const;
-
-private:
-    class DisplayEventThreadBase : public Thread {
-    protected:
-        wp<SurfaceFlinger> mFlinger;
-    public:
-        DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger);
-        virtual ~DisplayEventThreadBase();
-        virtual void onFirstRef() {
-            run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
-        }
-        virtual status_t acquireScreen() const { return NO_ERROR; };
-        virtual status_t releaseScreen() const { return NO_ERROR; };
-        virtual status_t initCheck() const = 0;
-    };
-
-    class DisplayEventThread : public DisplayEventThreadBase 
-    {
-        mutable Barrier mBarrier;
-    public:
-                DisplayEventThread(const sp<SurfaceFlinger>& flinger);
-        virtual ~DisplayEventThread();
-        virtual bool threadLoop();
-        virtual status_t readyToRun();
-        virtual status_t releaseScreen() const;
-        virtual status_t initCheck() const;
-    };
-
-    class ConsoleManagerThread : public DisplayEventThreadBase 
-    {
-        int consoleFd;
-        int vt_num;
-        int prev_vt_num;
-        vt_mode vm;
-        static void sigHandler(int sig);
-        static pid_t sSignalCatcherPid;
-    public:
-                ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
-        virtual ~ConsoleManagerThread();
-        virtual bool threadLoop();
-        virtual status_t readyToRun();
-        virtual void requestExit();
-        virtual status_t releaseScreen() const;
-        virtual status_t initCheck() const;
-    };
-
-    sp<DisplayEventThreadBase>  mDisplayEventThread;
-    mutable int                 mCanDraw;
-};
-
-}; // namespace android
-
-#endif // ANDROID_DISPLAY_HARDWARE_BASE_H
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
deleted file mode 100644
index ce7e9aa..0000000
--- a/libs/surfaceflinger/Layer.cpp
+++ /dev/null
@@ -1,630 +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 <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <cutils/properties.h>
-#include <cutils/native_handle.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-
-#include <surfaceflinger/Surface.h>
-
-#include "clz.h"
-#include "Layer.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-
-#define DEBUG_RESIZE    0
-
-
-namespace android {
-
-template <typename T> inline T min(T a, T b) {
-    return a<b ? a : b;
-}
-
-// ---------------------------------------------------------------------------
-
-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),
-        mNeedsBlending(true),
-        mNeedsDithering(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
-}
-
-void Layer::destroy()
-{
-    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;
-    }
-    mSurface.clear();
-}
-
-sp<LayerBaseClient::Surface> Layer::createSurface() const
-{
-    return mSurface;
-}
-
-status_t Layer::ditch()
-{
-    // the layer is not on screen anymore. free as much resources as possible
-    mFreezeLock.clear();
-    destroy();
-    return NO_ERROR;
-}
-
-status_t Layer::setBuffers( uint32_t w, uint32_t h,
-                            PixelFormat format, uint32_t flags)
-{
-    // this surfaces pixel format
-    PixelFormatInfo info;
-    status_t err = getPixelFormatInfo(format, &info);
-    if (err) return err;
-
-    // the display's pixel format
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    uint32_t const maxSurfaceDims = min(
-            hw.getMaxTextureSize(), hw.getMaxViewportDims());
-
-    // never allow a surface larger than what our underlying GL implementation
-    // can handle.
-    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
-        return BAD_VALUE;
-    }
-
-    PixelFormatInfo displayInfo;
-    getPixelFormatInfo(hw.getFormat(), &displayInfo);
-    const uint32_t hwFlags = hw.getFlags();
-    
-    mFormat = format;
-    mWidth  = w;
-    mHeight = 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);
-    return NO_ERROR;
-}
-
-void Layer::reloadTexture(const Region& dirty)
-{
-    Mutex::Autolock _l(mLock);
-    sp<GraphicBuffer> buffer(getFrontBufferLocked());
-    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
-        // to this context.
-        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;
-            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();
-                }
-                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();
-        }
-    }
-}
-
-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)) {
-        // 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
-        // has drawn the first time.
-
-        // If there is nothing under us, we paint the screen in black, otherwise
-        // we just skip this update.
-
-        // figure out if there is something below us
-        Region under;
-        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
-        const size_t count = drawingLayers.size();
-        for (size_t i=0 ; i<count ; ++i) {
-            const sp<LayerBase>& layer(drawingLayers[i]);
-            if (layer.get() == static_cast<LayerBase const*>(this))
-                break;
-            under.orSelf(layer->visibleRegionScreen);
-        }
-        // if not everything below us is covered, we plug the holes!
-        Region holes(clip.subtract(under));
-        if (!holes.isEmpty()) {
-            clearWithOpenGL(holes);
-        }
-        return;
-    }
-    drawWithOpenGL(clip, mTextures[index]);
-}
-
-sp<GraphicBuffer> Layer::requestBuffer(int index, int usage)
-{
-    sp<GraphicBuffer> buffer;
-
-    // this ensures our client doesn't go away while we're accessing
-    // the shared area.
-    sp<Client> ourClient(client.promote());
-    if (ourClient == 0) {
-        // oops, the client is already gone
-        return buffer;
-    }
-
-    /*
-     * 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;
-    { // 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();
-    }
-
-    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();
-    }
-
-    if (err || buffer->handle == 0) {
-        LOGE_IF(err || buffer->handle == 0,
-                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
-                this, index, w, h, strerror(-err));
-    } else {
-        LOGD_IF(DEBUG_RESIZE,
-                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
-                this, index, w, h, buffer->handle);
-    }
-
-    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();
-        }
-    }
-    return buffer;
-}
-
-uint32_t Layer::getEffectiveUsage(uint32_t usage) const
-{
-    /*
-     *  buffers used for software rendering, but h/w composition
-     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
-     *
-     *  buffers used for h/w rendering and h/w composition
-     *  are allocated with  HW_RENDER | HW_TEXTURE
-     *
-     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
-     *  are allocated with SW_READ_RARELY | HW_RENDER
-     *
-     */
-
-    if (mSecure) {
-        // secure buffer, don't store it into the GPU
-        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
-                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
-    } 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;
-        }
-    }
-    return usage;
-}
-
-uint32_t Layer::doTransaction(uint32_t flags)
-{
-    const Layer::State& front(drawingState());
-    const Layer::State& temp(currentState());
-
-    if ((front.requested_w != temp.requested_w) || 
-        (front.requested_h != temp.requested_h)) {
-        // 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()));
-
-        // 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.
-        setDrawingSize(temp.requested_w, temp.requested_h);
-
-        // all buffers need reallocation
-        lcblk->reallocate();
-    }
-
-    if (temp.sequence != front.sequence) {
-        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
-            // this surface is now hidden, so it shouldn't hold a freeze lock
-            // (it may never redraw, which is fine if it is hidden)
-            mFreezeLock.clear();
-        }
-    }
-        
-    return LayerBase::doTransaction(flags);
-}
-
-void Layer::setDrawingSize(uint32_t w, uint32_t h) {
-    Mutex::Autolock _l(mLock);
-    mWidth = w;
-    mHeight = h;
-}
-
-// ----------------------------------------------------------------------------
-// pageflip handling...
-// ----------------------------------------------------------------------------
-
-void Layer::lockPageFlip(bool& recomputeVisibleRegions)
-{
-    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 
-        // 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);
-        mPostedDirtyRegion.clear();
-        return;
-    }
-
-    // we retired a buffer, which becomes the new front buffer
-    mFrontBufferIndex = buf;
-
-    // get the dirty region
-    sp<GraphicBuffer> newFrontBuffer(getBuffer(buf));
-    if (newFrontBuffer != NULL) {
-        // compute the posted region
-        const Region dirty(lcblk->getDirtyRegion(buf));
-        mPostedDirtyRegion = dirty.intersect( newFrontBuffer->getBounds() );
-
-        // update the layer size and release freeze-lock
-        const Layer::State& front(drawingState());
-        if (newFrontBuffer->getWidth()  == front.requested_w &&
-            newFrontBuffer->getHeight() == front.requested_h)
-        {
-            if ((front.w != front.requested_w) ||
-                (front.h != front.requested_h))
-            {
-                // Here we pretend the transaction happened by updating the
-                // current and drawing states. Drawing state is only accessed
-                // in this thread, no need to have it locked
-                Layer::State& editDraw(mDrawingState);
-                editDraw.w = editDraw.requested_w;
-                editDraw.h = editDraw.requested_h;
-
-                // We also need to update the current state so that we don't
-                // end-up doing too much work during the next transaction.
-                // NOTE: We actually don't need hold the transaction lock here
-                // because State::w and State::h are only accessed from
-                // this thread
-                Layer::State& editTemp(currentState());
-                editTemp.w = editDraw.w;
-                editTemp.h = editDraw.h;
-
-                // recompute visible region
-                recomputeVisibleRegions = true;
-            }
-
-            // we now have the correct size, unfreeze the screen
-            mFreezeLock.clear();
-        }
-    } else {
-        // this should not happen unless we ran out of memory while
-        // allocating the buffer. we're hoping that things will get back
-        // to normal the next time the app tries to draw into this buffer.
-        // meanwhile, pretend the screen didn't update.
-        mPostedDirtyRegion.clear();
-    }
-
-    if (lcblk->getQueuedCount()) {
-        // signal an event if we have more buffers waiting
-        mFlinger->signalEvent();
-    }
-
-    if (!mPostedDirtyRegion.isEmpty()) {
-        reloadTexture( mPostedDirtyRegion );
-    }
-}
-
-void Layer::unlockPageFlip(
-        const Transform& planeTransform, Region& outDirtyRegion)
-{
-    Region dirtyRegion(mPostedDirtyRegion);
-    if (!dirtyRegion.isEmpty()) {
-        mPostedDirtyRegion.clear();
-        // The dirty region is given in the layer's coordinate space
-        // transform the dirty region by the surface's transformation
-        // and the global transformation.
-        const Layer::State& s(drawingState());
-        const Transform tr(planeTransform * s.transform);
-        dirtyRegion = tr.transform(dirtyRegion);
-
-        // At this point, the dirty region is in screen space.
-        // Make sure it's constrained by the visible region (which
-        // is in screen space as well).
-        dirtyRegion.andSelf(visibleRegionScreen);
-        outDirtyRegion.orSelf(dirtyRegion);
-    }
-    if (visibleRegionScreen.isEmpty()) {
-        // an invisible layer should not hold a freeze-lock
-        // (because it may never be updated and thereore 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);
-}
-
-// ---------------------------------------------------------------------------
-
-Layer::SurfaceLayer::SurfaceLayer(const sp<SurfaceFlinger>& flinger,
-        SurfaceID id, const sp<Layer>& owner)
-    : Surface(flinger, id, owner->getIdentity(), owner)
-{
-}
-
-Layer::SurfaceLayer::~SurfaceLayer()
-{
-}
-
-sp<GraphicBuffer> Layer::SurfaceLayer::requestBuffer(int index, int 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);
-        }
-    }
-    return buffer;
-}
-
-// ---------------------------------------------------------------------------
-
-
-}; // namespace android
diff --git a/libs/surfaceflinger/Layer.h b/libs/surfaceflinger/Layer.h
deleted file mode 100644
index 743afb4..0000000
--- a/libs/surfaceflinger/Layer.h
+++ /dev/null
@@ -1,134 +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_LAYER_H
-#define ANDROID_LAYER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-#include <pixelflinger/pixelflinger.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include "LayerBase.h"
-#include "Transform.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Client;
-class FreezeLock;
-
-// ---------------------------------------------------------------------------
-
-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);
-
-        virtual ~Layer();
-
-    status_t setBuffers(uint32_t w, uint32_t h, 
-            PixelFormat format, uint32_t flags=0);
-
-    void setDrawingSize(uint32_t w, uint32_t h);
-
-    virtual void onDraw(const Region& clip) const;
-    virtual uint32_t doTransaction(uint32_t transactionFlags);
-    virtual void lockPageFlip(bool& recomputeVisibleRegions);
-    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-    virtual void finishPageFlip();
-    virtual bool needsBlending() const      { return mNeedsBlending; }
-    virtual bool needsDithering() const     { return mNeedsDithering; }
-    virtual bool isSecure() const           { return mSecure; }
-    virtual sp<Surface> createSurface() const;
-    virtual status_t ditch();
-    
-    // only for debugging
-    inline sp<GraphicBuffer> getBuffer(int i) { return mBuffers[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; }
-
-private:
-    inline sp<GraphicBuffer> getFrontBufferLocked() {
-        return mBuffers[mFrontBufferIndex];
-    }
- 
-    void reloadTexture(const Region& dirty);
-
-    uint32_t getEffectiveUsage(uint32_t usage) const;
-
-    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();
-    private:
-        virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
-        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;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_H
diff --git a/libs/surfaceflinger/LayerBase.cpp b/libs/surfaceflinger/LayerBase.cpp
deleted file mode 100644
index a8b735e..0000000
--- a/libs/surfaceflinger/LayerBase.cpp
+++ /dev/null
@@ -1,829 +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 <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include <hardware/hardware.h>
-
-#include "clz.h"
-#include "LayerBase.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.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";
-
-// ---------------------------------------------------------------------------
-
-LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
-    : dpy(display), contentDirty(false),
-      mFlinger(flinger),
-      mTransformed(false),
-      mUseLinearFiltering(false),
-      mOrientation(0),
-      mLeft(0), mTop(0),
-      mTransactionFlags(0),
-      mPremultipliedAlpha(true), mDebug(false),
-      mInvalidate(0)
-{
-    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
-    mFlags = hw.getFlags();
-}
-
-LayerBase::~LayerBase()
-{
-}
-
-void LayerBase::setName(const String8& name) {
-    mName = name;
-}
-
-String8 LayerBase::getName() const {
-    return mName;
-}
-
-const GraphicPlane& LayerBase::graphicPlane(int dpy) const
-{ 
-    return mFlinger->graphicPlane(dpy);
-}
-
-GraphicPlane& LayerBase::graphicPlane(int dpy)
-{
-    return mFlinger->graphicPlane(dpy); 
-}
-
-void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
-{
-    uint32_t layerFlags = 0;
-    if (flags & ISurfaceComposer::eHidden)
-        layerFlags = ISurfaceComposer::eLayerHidden;
-
-    if (flags & ISurfaceComposer::eNonPremultiplied)
-        mPremultipliedAlpha = false;
-
-    mCurrentState.z             = 0;
-    mCurrentState.w             = w;
-    mCurrentState.h             = h;
-    mCurrentState.requested_w   = w;
-    mCurrentState.requested_h   = h;
-    mCurrentState.alpha         = 0xFF;
-    mCurrentState.flags         = layerFlags;
-    mCurrentState.sequence      = 0;
-    mCurrentState.transform.set(0, 0);
-
-    // drawing state & current state are identical
-    mDrawingState = mCurrentState;
-}
-
-void LayerBase::commitTransaction() {
-    mDrawingState = mCurrentState;
-}
-void LayerBase::forceVisibilityTransaction() {
-    // this can be called without SurfaceFlinger.mStateLock, but if we
-    // can atomically increment the sequence number, it doesn't matter.
-    android_atomic_inc(&mCurrentState.sequence);
-    requestTransaction();
-}
-bool LayerBase::requestTransaction() {
-    int32_t old = setTransactionFlags(eTransactionNeeded);
-    return ((old & eTransactionNeeded) == 0);
-}
-uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
-    return android_atomic_or(flags, &mTransactionFlags);
-}
-
-bool LayerBase::setPosition(int32_t x, int32_t y) {
-    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.transform.set(x, y);
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setLayer(uint32_t z) {
-    if (mCurrentState.z == z)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.z = z;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setSize(uint32_t w, uint32_t h) {
-    if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
-        return false;
-    mCurrentState.requested_w = w;
-    mCurrentState.requested_h = h;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setAlpha(uint8_t alpha) {
-    if (mCurrentState.alpha == alpha)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.alpha = alpha;
-    requestTransaction();
-    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);
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setTransparentRegionHint(const Region& transparent) {
-    // TODO: check the region has changed
-    mCurrentState.sequence++;
-    mCurrentState.transparentRegion = transparent;
-    requestTransaction();
-    return true;
-}
-bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
-    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
-    if (mCurrentState.flags == newFlags)
-        return false;
-    mCurrentState.sequence++;
-    mCurrentState.flags = newFlags;
-    requestTransaction();
-    return true;
-}
-
-Rect LayerBase::visibleBounds() const
-{
-    return mTransformedBounds;
-}      
-
-void LayerBase::setVisibleRegion(const Region& visibleRegion) {
-    // always called from main thread
-    visibleRegionScreen = visibleRegion;
-}
-
-void LayerBase::setCoveredRegion(const Region& coveredRegion) {
-    // always called from main thread
-    coveredRegionScreen = coveredRegion;
-}
-
-uint32_t LayerBase::doTransaction(uint32_t flags)
-{
-    const Layer::State& front(drawingState());
-    const Layer::State& temp(currentState());
-
-    if ((front.requested_w != temp.requested_w) ||
-        (front.requested_h != temp.requested_h))  {
-        // resize the layer, set the physical size to the requested size
-        Layer::State& editTemp(currentState());
-        editTemp.w = temp.requested_w;
-        editTemp.h = temp.requested_h;
-    }
-
-    if ((front.w != temp.w) || (front.h != temp.h)) {
-        // invalidate and recompute the visible regions if needed
-        flags |= Layer::eVisibleRegion;
-    }
-
-    if (temp.sequence != front.sequence) {
-        // invalidate and recompute the visible regions if needed
-        flags |= eVisibleRegion;
-        this->contentDirty = true;
-
-        const bool linearFiltering = mUseLinearFiltering;
-        mUseLinearFiltering = 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;
-            }
-        }
-    }
-
-    // Commit the transaction
-    commitTransaction();
-    return flags;
-}
-
-void LayerBase::validateVisibility(const Transform& planeTransform)
-{
-    const Layer::State& s(drawingState());
-    const Transform tr(planeTransform * s.transform);
-    const bool transformed = tr.transformed();
-   
-    uint32_t w = s.w;
-    uint32_t h = s.h;    
-    tr.transform(mVertices[0], 0, 0);
-    tr.transform(mVertices[1], 0, h);
-    tr.transform(mVertices[2], w, h);
-    tr.transform(mVertices[3], w, 0);
-    if (UNLIKELY(transformed)) {
-        // NOTE: here we could also punt if we have too many rectangles
-        // in the transparent region
-        if (tr.preserveRects()) {
-            // transform the transparent region
-            transparentRegionScreen = tr.transform(s.transparentRegion);
-        } else {
-            // transformation too complex, can't do the transparent region
-            // optimization.
-            transparentRegionScreen.clear();
-        }
-    } else {
-        transparentRegionScreen = s.transparentRegion;
-    }
-
-    // cache a few things...
-    mOrientation = tr.getOrientation();
-    mTransformedBounds = tr.makeBounds(w, h);
-    mTransformed = transformed;
-    mLeft = tr.tx();
-    mTop  = tr.ty();
-}
-
-void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
-{
-}
-
-void LayerBase::unlockPageFlip(
-        const Transform& planeTransform, Region& outDirtyRegion)
-{
-    if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
-        outDirtyRegion.orSelf(visibleRegionScreen);
-    }
-}
-
-void LayerBase::finishPageFlip()
-{
-}
-
-void LayerBase::invalidate()
-{
-    if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
-        mFlinger->signalEvent();
-    }
-}
-
-void LayerBase::drawRegion(const Region& reg) const
-{
-    Region::const_iterator it = reg.begin();
-    Region::const_iterator const end = reg.end();
-    if (it != end) {
-        Rect r;
-        const DisplayHardware& hw(graphicPlane(0).displayHardware());
-        const int32_t fbWidth  = hw.getWidth();
-        const int32_t fbHeight = hw.getHeight();
-        const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 
-                { fbWidth, fbHeight }, { 0, fbHeight }  };
-        glVertexPointer(2, GL_SHORT, 0, vertices);
-        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); 
-        }
-    }
-}
-
-void LayerBase::draw(const Region& inClip) 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
-{
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const uint32_t fbHeight = hw.getHeight();
-    glColor4x(red,green,blue,alpha);
-    glDisable(GL_TEXTURE_2D);
-    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);
-    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); 
-    }
-}
-
-void LayerBase::clearWithOpenGL(const Region& clip) const
-{
-    clearWithOpenGL(clip,0,0,0,0);
-}
-
-void LayerBase::drawWithOpenGL(const Region& clip, const Texture& texture) const
-{
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const uint32_t fbHeight = hw.getHeight();
-    const State& s(drawingState());
-    
-    // bind our texture
-    validateTexture(texture.name);
-    uint32_t width  = texture.width; 
-    uint32_t height = texture.height;
-    
-    glEnable(GL_TEXTURE_2D);
-
-    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;
-        } else {
-            env = GL_REPLACE;
-            src = GL_SRC_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);
-    } else {
-        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 {
-            glDisable(GL_BLEND);
-        }
-    }
-
-    Region::const_iterator it = clip.begin();
-    Region::const_iterator const end = clip.end();
-
-    //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;
-    }
-
-    if (texture.NPOTAdjust) {
-        glScalef(texture.wScale, texture.hScale, 1.0f);
-    }
-
-    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-    glVertexPointer(2, GL_FIXED, 0, mVertices);
-    glTexCoordPointer(2, GL_FIXED, 0, texCoords);
-
-    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);
-}
-
-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);
-    }
-}
-
-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::loadTexture(Texture* texture, 
-        const Region& dirty, const GGLSurface& t) 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);
-        }
-    }
-}
-
-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;
-
-LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client, int32_t i)
-    : LayerBase(flinger, display), lcblk(NULL), client(client), mIndex(i),
-      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);
-    }
-    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()
-{
-    sp<Surface> s;
-    Mutex::Autolock _l(mLock);
-    s = mClientSurface.promote();
-    if (s == 0) {
-        s = createSurface();
-        mClientSurface = s;
-    }
-    return s;
-}
-
-sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
-{
-    return new Surface(mFlinger, clientIndex(), mIdentity,
-            const_cast<LayerBaseClient *>(this));
-}
-
-// called with SurfaceFlinger::mStateLock as soon as the layer is entered
-// in the purgatory list
-void LayerBaseClient::onRemoved()
-{
-    // wake up the condition
-    lcblk->setStatus(NO_INIT);
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBaseClient::Surface::Surface(
-        const sp<SurfaceFlinger>& flinger,
-        SurfaceID id, int identity, 
-        const sp<LayerBaseClient>& owner) 
-    : mFlinger(flinger), mToken(id), mIdentity(identity), mOwner(owner)
-{
-}
-
-LayerBaseClient::Surface::~Surface() 
-{
-    /*
-     * This is a good place to clean-up all client resources 
-     */
-
-    // destroy client resources
-    sp<LayerBaseClient> layer = getOwner();
-    if (layer != 0) {
-        mFlinger->destroySurface(layer);
-    }
-}
-
-sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
-    sp<LayerBaseClient> owner(mOwner.promote());
-    return owner;
-}
-
-status_t LayerBaseClient::Surface::onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch (code) {
-        case REGISTER_BUFFERS:
-        case UNREGISTER_BUFFERS:
-        case CREATE_OVERLAY:
-        {
-            if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
-                IPCThreadState* ipc = IPCThreadState::self();
-                const int pid = ipc->getCallingPid();
-                const int uid = ipc->getCallingUid();
-                LOGE("Permission Denial: "
-                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                return PERMISSION_DENIED;
-            }
-        }
-    }
-    return BnSurface::onTransact(code, data, reply, flags);
-}
-
-sp<GraphicBuffer> LayerBaseClient::Surface::requestBuffer(int index, int usage) 
-{
-    return NULL; 
-}
-
-status_t LayerBaseClient::Surface::registerBuffers(
-        const ISurface::BufferHeap& buffers) 
-{ 
-    return INVALID_OPERATION; 
-}
-
-void LayerBaseClient::Surface::postBuffer(ssize_t offset) 
-{
-}
-
-void LayerBaseClient::Surface::unregisterBuffers() 
-{
-}
-
-sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
-        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
-{
-    return NULL;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
deleted file mode 100644
index 62ec839..0000000
--- a/libs/surfaceflinger/LayerBase.h
+++ /dev/null
@@ -1,389 +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_LAYER_BASE_H
-#define ANDROID_LAYER_BASE_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-#include <GLES/gl.h>
-
-#include <utils/RefBase.h>
-
-#include <ui/Region.h>
-#include <ui/Overlay.h>
-
-#include <surfaceflinger/ISurfaceFlingerClient.h>
-#include <private/surfaceflinger/SharedBufferStack.h>
-#include <private/surfaceflinger/LayerState.h>
-
-#include <pixelflinger/pixelflinger.h>
-
-#include "Transform.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class DisplayHardware;
-class Client;
-class GraphicBuffer;
-class GraphicPlane;
-class SurfaceFlinger;
-
-// ---------------------------------------------------------------------------
-
-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(); }
-    };
-
-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);
-    
-    DisplayID           dpy;
-    mutable bool        contentDirty;
-            Region      visibleRegionScreen;
-            Region      transparentRegionScreen;
-            Region      coveredRegionScreen;
-            
-            struct State {
-                uint32_t        w;
-                uint32_t        h;
-                uint32_t        requested_w;
-                uint32_t        requested_h;
-                uint32_t        z;
-                uint8_t         alpha;
-                uint8_t         flags;
-                uint8_t         reserved[2];
-                int32_t         sequence;   // changes when visible regions can change
-                uint32_t        tint;
-                Transform       transform;
-                Region          transparentRegion;
-            };
-
-            void setName(const String8& name);
-            String8 getName() const;
-
-            // modify current state
-            bool setPosition(int32_t x, int32_t y);
-            bool setLayer(uint32_t z);
-            bool setSize(uint32_t w, uint32_t h);
-            bool setAlpha(uint8_t alpha);
-            bool setMatrix(const layer_state_t::matrix22_t& matrix);
-            bool setTransparentRegionHint(const Region& opaque);
-            bool setFlags(uint8_t flags, uint8_t mask);
-            
-            void commitTransaction();
-            bool requestTransaction();
-            void forceVisibilityTransaction();
-            
-            uint32_t getTransactionFlags(uint32_t flags);
-            uint32_t setTransactionFlags(uint32_t flags);
-            
-            Rect visibleBounds() const;
-            void drawRegion(const Region& reg) const;
-
-            void invalidate();
-
-    /**
-     * draw - performs some global clipping optimizations
-     * and calls onDraw().
-     * Typically this method is not overridden, instead implement onDraw()
-     * to perform the actual drawing.  
-     */
-    virtual void draw(const Region& clip) const;
-    
-    /**
-     * onDraw - draws the surface.
-     */
-    virtual void onDraw(const Region& clip) const = 0;
-    
-    /**
-     * initStates - called just after construction
-     */
-    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
-    
-    /**
-     * doTransaction - process the transaction. This is a good place to figure
-     * out which attributes of the surface have changed.
-     */
-    virtual uint32_t doTransaction(uint32_t transactionFlags);
-    
-    /**
-     * setVisibleRegion - called to set the new visible region. This gives
-     * a chance to update the new visible region or record the fact it changed.
-     */
-    virtual void setVisibleRegion(const Region& visibleRegion);
-    
-    /**
-     * setCoveredRegion - called when the covered region changes. The covered
-     * region corresponds to any area of the surface that is covered
-     * (transparently or not) by another surface.
-     */
-    virtual void setCoveredRegion(const Region& coveredRegion);
-
-    /**
-     * validateVisibility - cache a bunch of things
-     */
-    virtual void validateVisibility(const Transform& globalTransform);
-
-    /**
-     * lockPageFlip - called each time the screen is redrawn and returns whether
-     * the visible regions need to be recomputed (this is a fairly heavy
-     * operation, so this should be set only if needed). Typically this is used
-     * to figure out if the content or size of a surface has changed.
-     */
-    virtual void lockPageFlip(bool& recomputeVisibleRegions);
-    
-    /**
-     * unlockPageFlip - called each time the screen is redrawn. updates the
-     * final dirty region wrt the planeTransform.
-     * At this point, all visible regions, surface position and size, etc... are
-     * correct.
-     */
-    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-    
-    /**
-     * finishPageFlip - called after all surfaces have drawn.
-     */
-    virtual void finishPageFlip();
-    
-    /**
-     * needsBlending - true if this surface needs blending
-     */
-    virtual bool needsBlending() const  { return false; }
-
-    /**
-     * needsDithering - true if this surface needs dithering
-     */
-    virtual bool needsDithering() const { return false; }
-
-    /**
-     * transformed -- true is this surface needs a to be transformed
-     */
-    virtual bool transformed() const    { return mTransformed; }
-
-    /**
-     * isSecure - true if this surface is secure, that is if it prevents
-     * screenshots or VNC servers.
-     */
-    virtual bool isSecure() const       { return false; }
-
-    /** Called from the main thread, when the surface is removed from the
-     * draw list */
-    virtual status_t ditch() { return NO_ERROR; }
-
-    /** called with the state lock when the surface is removed from the
-     *  current list */
-    virtual void onRemoved() { };
-    
-    
-    enum { // flags for doTransaction()
-        eVisibleRegion      = 0x00000002,
-    };
-
-
-    inline  const State&    drawingState() const    { return mDrawingState; }
-    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; }
-    
-protected:
-    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) 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;
-          
-                sp<SurfaceFlinger> mFlinger;
-                uint32_t        mFlags;
-
-                // cached during validateVisibility()
-                bool            mTransformed;
-                bool            mUseLinearFiltering;
-                int32_t         mOrientation;
-                GLfixed         mVertices[4][2];
-                Rect            mTransformedBounds;
-                int             mLeft;
-                int             mTop;
-            
-                // these are protected by an external lock
-                State           mCurrentState;
-                State           mDrawingState;
-    volatile    int32_t         mTransactionFlags;
-
-                // don't change, don't need a lock
-                bool            mPremultipliedAlpha;
-                String8         mName;
-    mutable     bool            mDebug;
-
-
-                // atomic
-    volatile    int32_t         mInvalidate;
-                
-
-protected:
-    virtual ~LayerBase();
-
-private:
-    LayerBase(const LayerBase& rhs);
-    void validateTexture(GLint textureName) const;
-};
-
-
-// ---------------------------------------------------------------------------
-
-class LayerBaseClient : public LayerBase
-{
-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);
-    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();
-
-
-    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, 
-                const sp<LayerBaseClient>& owner);
-        virtual ~Surface();
-        virtual status_t onTransact(uint32_t code, const Parcel& data,
-                Parcel* reply, uint32_t flags);
-        sp<LayerBaseClient> getOwner() const;
-
-    private:
-        virtual sp<GraphicBuffer> requestBuffer(int index, int usage);
-        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers); 
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h,
-                int32_t format, int32_t orientation);
-
-    protected:
-        friend class LayerBaseClient;
-        sp<SurfaceFlinger>  mFlinger;
-        int32_t             mToken;
-        int32_t             mIdentity;
-        wp<LayerBaseClient> mOwner;
-    };
-
-    friend class Surface;
-
-private:
-                int32_t         mIndex;
-    mutable     Mutex           mLock;
-    mutable     wp<Surface>     mClientSurface;
-    // only read
-    const       uint32_t        mIdentity;
-    static      int32_t         sIdentity;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BASE_H
diff --git a/libs/surfaceflinger/LayerBlur.cpp b/libs/surfaceflinger/LayerBlur.cpp
deleted file mode 100644
index 5fd7904..0000000
--- a/libs/surfaceflinger/LayerBlur.cpp
+++ /dev/null
@@ -1,265 +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 <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <GLES/gl.h>
-#include <GLES/glext.h>
-
-#include "clz.h"
-#include "BlurFilter.h"
-#include "LayerBlur.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-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),
-          mRefreshCache(true), mCacheAge(0), mTextureName(-1U),
-          mWidthScale(1.0f), mHeightScale(1.0f),
-          mBlurFormat(GGL_PIXEL_FORMAT_RGB_565)
-{
-}
-
-LayerBlur::~LayerBlur()
-{
-    if (mTextureName != -1U) {
-        glDeleteTextures(1, &mTextureName);
-    }
-}
-
-void LayerBlur::setVisibleRegion(const Region& visibleRegion)
-{
-    LayerBaseClient::setVisibleRegion(visibleRegion);
-    if (visibleRegionScreen.isEmpty()) {
-        if (mTextureName != -1U) {
-            // We're not visible, free the texture up.
-            glBindTexture(GL_TEXTURE_2D, 0);
-            glDeleteTextures(1, &mTextureName);
-            mTextureName = -1U;
-        }
-    }
-}
-
-uint32_t LayerBlur::doTransaction(uint32_t flags)
-{
-    // we're doing a transaction, refresh the cache!
-    if (!mFlinger->isFrozen()) {
-        mRefreshCache = true;
-        mCacheDirty = true;
-        flags |= eVisibleRegion;
-        this->contentDirty = true;
-    }
-    return LayerBase::doTransaction(flags);    
-}
-
-void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion)
-{
-    // this code-path must be as tight as possible, it's called each time
-    // the screen is composited.
-    if (UNLIKELY(!visibleRegionScreen.isEmpty())) {
-        // if anything visible below us is invalidated, the cache becomes dirty
-        if (!mCacheDirty && 
-                !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) {
-            mCacheDirty = true;
-        }
-        if (mCacheDirty) {
-            if (!mFlinger->isFrozen()) {
-                // update everything below us that is visible
-                outDirtyRegion.orSelf(visibleRegionScreen);
-                nsecs_t now = systemTime();
-                if ((now - mCacheAge) >= ms2ns(500)) {
-                    mCacheAge = now;
-                    mRefreshCache = true;
-                    mCacheDirty = false;
-                } else {
-                    if (!mAutoRefreshPending) {
-                        mFlinger->signalDelayedEvent(ms2ns(500));
-                        mAutoRefreshPending = true;
-                    }
-                }
-            }
-        }
-    }
-    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
-}
-
-void LayerBlur::onDraw(const Region& clip) const
-{
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const uint32_t fbHeight = hw.getHeight();
-    int x = mTransformedBounds.left;
-    int y = mTransformedBounds.top;
-    int w = mTransformedBounds.width();
-    int h = mTransformedBounds.height();
-    GLint X = x;
-    GLint Y = fbHeight - (y + h);
-    if (X < 0) {
-        w += X;
-        X = 0;
-    }
-    if (Y < 0) {
-        h += Y;
-        Y = 0;
-    }
-    if (w<0 || h<0) {
-        // we're outside of the framebuffer
-        return;
-    }
-
-    if (mTextureName == -1U) {
-        // create the texture name the first time
-        // can't do that in the ctor, because it runs in another thread.
-        glGenTextures(1, &mTextureName);
-        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat);
-        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType);
-        if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) {
-            mReadFormat = GL_RGBA;
-            mReadType = GL_UNSIGNED_BYTE;
-            mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888;
-        }
-    }
-
-    Region::const_iterator it = clip.begin();
-    Region::const_iterator const end = clip.end();
-    if (it != end) {
-        glEnable(GL_TEXTURE_2D);
-        glBindTexture(GL_TEXTURE_2D, mTextureName);
-
-        if (mRefreshCache) {
-            mRefreshCache = false;
-            mAutoRefreshPending = false;
-
-            int32_t pixelSize = 4;
-            int32_t s = w;
-            if (mReadType == GL_UNSIGNED_SHORT_5_6_5) {
-                // allocate enough memory for 4-bytes (2 pixels) aligned data
-                s = (w + 1) & ~1;
-                pixelSize = 2;
-            }
-
-            uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize);
-
-            // This reads the frame-buffer, so a h/w GL would have to
-            // finish() its rendering first. we don't want to do that
-            // too often. Read data is 4-bytes aligned.
-            glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels);
-
-            // blur that texture.
-            GGLSurface bl;
-            bl.version = sizeof(GGLSurface);
-            bl.width = w;
-            bl.height = h;
-            bl.stride = s;
-            bl.format = mBlurFormat;
-            bl.data = (GGLubyte*)pixels;            
-            blurFilter(&bl, 8, 2);
-
-            if (mFlags & (DisplayHardware::NPOT_EXTENSION)) {
-                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
-                        mReadFormat, mReadType, pixels);
-                mWidthScale  = 1.0f / w;
-                mHeightScale =-1.0f / h;
-                mYOffset = 0;
-            } else {
-                GLuint tw = 1 << (31 - clz(w));
-                GLuint th = 1 << (31 - clz(h));
-                if (tw < GLuint(w)) tw <<= 1;
-                if (th < GLuint(h)) th <<= 1;
-                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0,
-                        mReadFormat, mReadType, NULL);
-                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 
-                        mReadFormat, mReadType, pixels);
-                mWidthScale  = 1.0f / tw;
-                mHeightScale =-1.0f / th;
-                mYOffset = th-h;
-            }
-
-            free((void*)pixels);
-        }
-
-        const State& s = drawingState();
-        if (UNLIKELY(s.alpha < 0xFF)) {
-            const GGLfixed alpha = (s.alpha << 16)/255;
-            glColor4x(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);
-        } else {
-            glDisable(GL_BLEND);
-        }
-
-        if (mFlags & DisplayHardware::SLOW_CONFIG) {
-            glDisable(GL_DITHER);
-        } else {
-            glEnable(GL_DITHER);
-        }
-
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        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);
-            }
-        }
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
deleted file mode 100644
index 5b63dec..0000000
--- a/libs/surfaceflinger/LayerBlur.h
+++ /dev/null
@@ -1,69 +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_LAYER_BLUR_H
-#define ANDROID_LAYER_BLUR_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/Region.h>
-
-#include "LayerBase.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-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);
-        virtual ~LayerBlur();
-
-    virtual void onDraw(const Region& clip) const;
-    virtual bool needsBlending() const  { return true; }
-    virtual bool isSecure() const       { return false; }
-
-    virtual uint32_t doTransaction(uint32_t flags);
-    virtual void setVisibleRegion(const Region& visibleRegion);
-    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
-
-private:
-            bool    mCacheDirty;
-    mutable bool    mRefreshCache;
-    mutable bool    mAutoRefreshPending;
-            nsecs_t mCacheAge;
-    mutable GLuint  mTextureName;
-    mutable GLfloat mWidthScale;
-    mutable GLfloat mHeightScale;
-    mutable GLfloat mYOffset;
-    mutable GLint   mReadFormat;
-    mutable GLint   mReadType;
-    mutable uint32_t mBlurFormat;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BLUR_H
diff --git a/libs/surfaceflinger/LayerBuffer.cpp b/libs/surfaceflinger/LayerBuffer.cpp
deleted file mode 100644
index 5c21593..0000000
--- a/libs/surfaceflinger/LayerBuffer.cpp
+++ /dev/null
@@ -1,727 +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 <stdlib.h>
-#include <stdint.h>
-#include <math.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/StopWatch.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/PixelFormat.h>
-#include <ui/FramebufferNativeWindow.h>
-#include <ui/Rect.h>
-#include <ui/Region.h>
-
-#include <hardware/copybit.h>
-
-#include "LayerBuffer.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-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),
-      mNeedsBlending(false), mBlitEngine(0)
-{
-}
-
-LayerBuffer::~LayerBuffer()
-{
-    if (mBlitEngine) {
-        copybit_close(mBlitEngine);
-    }
-}
-
-void LayerBuffer::onFirstRef()
-{
-    LayerBaseClient::onFirstRef();
-    mSurface = new SurfaceLayerBuffer(mFlinger, clientIndex(),
-            const_cast<LayerBuffer *>(this));
-
-    hw_module_t const* module = (hw_module_t const*)sGrallocModule;
-    if (!module) {
-        // NOTE: technically there is a race here, but it shouldn't
-        // cause any problem since hw_get_module() always returns
-        // the same value.
-        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
-            sGrallocModule = (gralloc_module_t const *)module;
-        }
-    }
-
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        copybit_open(module, &mBlitEngine);
-    }
-}
-
-sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
-{
-    return mSurface;
-}
-
-status_t LayerBuffer::ditch()
-{
-    mSurface.clear();
-    return NO_ERROR;
-}
-
-bool LayerBuffer::needsBlending() const {
-    return mNeedsBlending;
-}
-
-void LayerBuffer::setNeedsBlending(bool blending) {
-    mNeedsBlending = blending;
-}
-
-void LayerBuffer::postBuffer(ssize_t offset)
-{
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->postBuffer(offset);
-}
-
-void LayerBuffer::unregisterBuffers()
-{
-    sp<Source> source(clearSource());
-    if (source != 0)
-        source->unregisterBuffers();
-}
-
-uint32_t LayerBuffer::doTransaction(uint32_t flags)
-{
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->onTransaction(flags);
-    uint32_t res = LayerBase::doTransaction(flags);
-    // we always want filtering for these surfaces
-    mUseLinearFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG);
-    return res;
-}
-
-void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
-        Region& outDirtyRegion)
-{
-    // this code-path must be as tight as possible, it's called each time
-    // the screen is composited.
-    sp<Source> source(getSource());
-    if (source != 0)
-        source->onVisibilityResolved(planeTransform);
-    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);    
-}
-
-void LayerBuffer::onDraw(const Region& clip) const
-{
-    sp<Source> source(getSource());
-    if (LIKELY(source != 0)) {
-        source->onDraw(clip);
-    } else {
-        clearWithOpenGL(clip);
-    }
-}
-
-bool LayerBuffer::transformed() const
-{
-    sp<Source> source(getSource());
-    if (LIKELY(source != 0))
-        return source->transformed();
-    return false;
-}
-
-void LayerBuffer::serverDestroy()
-{
-    sp<Source> source(clearSource());
-    if (source != 0) {
-        source->destroy();
-    }
-}
-
-/**
- * This creates a "buffer" source for this surface
- */
-status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
-{
-    Mutex::Autolock _l(mLock);
-    if (mSource != 0)
-        return INVALID_OPERATION;
-
-    sp<BufferSource> source = new BufferSource(*this, buffers);
-
-    status_t result = source->getStatus();
-    if (result == NO_ERROR) {
-        mSource = source;
-    }
-    return result;
-}    
-
-/**
- * This creates an "overlay" source for this surface
- */
-sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f,
-        int32_t orientation)
-{
-    sp<OverlayRef> result;
-    Mutex::Autolock _l(mLock);
-    if (mSource != 0)
-        return result;
-
-    sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f, orientation);
-    if (result != 0) {
-        mSource = source;
-    }
-    return result;
-}
-
-sp<LayerBuffer::Source> LayerBuffer::getSource() const {
-    Mutex::Autolock _l(mLock);
-    return mSource;
-}
-
-sp<LayerBuffer::Source> LayerBuffer::clearSource() {
-    sp<Source> source;
-    Mutex::Autolock _l(mLock);
-    source = mSource;
-    mSource.clear();
-    return source;
-}
-
-// ============================================================================
-// 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()
-{
-    unregisterBuffers();
-}
-
-status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers(
-        const ISurface::BufferHeap& buffers)
-{
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        return owner->registerBuffers(buffers);
-    return NO_INIT;
-}
-
-void LayerBuffer::SurfaceLayerBuffer::postBuffer(ssize_t offset)
-{
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        owner->postBuffer(offset);
-}
-
-void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers()
-{
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        owner->unregisterBuffers();
-}
-
-sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(
-        uint32_t w, uint32_t h, int32_t format, int32_t orientation) {
-    sp<OverlayRef> result;
-    sp<LayerBuffer> owner(getOwner());
-    if (owner != 0)
-        result = owner->createOverlay(w, h, format, orientation);
-    return result;
-}
-
-// ============================================================================
-// LayerBuffer::Buffer
-// ============================================================================
-
-LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
-        ssize_t offset, size_t bufferSize)
-    : mBufferHeap(buffers), mSupportsCopybit(false)
-{
-    NativeBuffer& src(mNativeBuffer);
-    src.crop.l = 0;
-    src.crop.t = 0;
-    src.crop.r = buffers.w;
-    src.crop.b = buffers.h;
-
-    src.img.w       = buffers.hor_stride ?: buffers.w;
-    src.img.h       = buffers.ver_stride ?: buffers.h;
-    src.img.format  = buffers.format;
-    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
-    src.img.handle  = 0;
-
-    gralloc_module_t const * module = LayerBuffer::getGrallocModule();
-    if (module && module->perform) {
-        int err = module->perform(module,
-                GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
-                buffers.heap->heapID(), bufferSize,
-                offset, buffers.heap->base(),
-                &src.img.handle);
-
-        // we can fail here is the passed buffer is purely software
-        mSupportsCopybit = (err == NO_ERROR);
-    }
- }
-
-LayerBuffer::Buffer::~Buffer()
-{
-    NativeBuffer& src(mNativeBuffer);
-    if (src.img.handle) {
-        native_handle_delete(src.img.handle);
-    }
-}
-
-// ============================================================================
-// LayerBuffer::Source
-// LayerBuffer::BufferSource
-// LayerBuffer::OverlaySource
-// ============================================================================
-
-LayerBuffer::Source::Source(LayerBuffer& layer)
-    : mLayer(layer)
-{    
-}
-LayerBuffer::Source::~Source() {    
-}
-void LayerBuffer::Source::onDraw(const Region& clip) const {
-}
-void LayerBuffer::Source::onTransaction(uint32_t flags) {
-}
-void LayerBuffer::Source::onVisibilityResolved(
-        const Transform& planeTransform) {
-}
-void LayerBuffer::Source::postBuffer(ssize_t offset) {
-}
-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)
-{
-    if (buffers.heap == NULL) {
-        // this is allowed, but in this case, it is illegal to receive
-        // postBuffer(). The surface just erases the framebuffer with
-        // fully transparent pixels.
-        mBufferHeap = buffers;
-        mLayer.setNeedsBlending(false);
-        return;
-    }
-
-    status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
-    if (err != NO_ERROR) {
-        LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
-        mStatus = err;
-        return;
-    }
-    
-    PixelFormatInfo info;
-    err = getPixelFormatInfo(buffers.format, &info);
-    if (err != NO_ERROR) {
-        LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
-                buffers.format, strerror(err));
-        mStatus = err;
-        return;
-    }
-
-    if (buffers.hor_stride<0 || buffers.ver_stride<0) {
-        LOGE("LayerBuffer::BufferSource: invalid parameters "
-             "(w=%d, h=%d, xs=%d, ys=%d)", 
-             buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
-        mStatus = BAD_VALUE;
-        return;
-    }
-
-    mBufferHeap = buffers;
-    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
-    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
-    mLayer.forceVisibilityTransaction();
-}
-
-LayerBuffer::BufferSource::~BufferSource()
-{    
-    class MessageDestroyTexture : public MessageBase {
-        SurfaceFlinger* flinger;
-        GLuint name;
-    public:
-        MessageDestroyTexture(
-                SurfaceFlinger* flinger, GLuint name)
-            : flinger(flinger), name(name) { }
-        virtual bool handler() {
-            glDeleteTextures(1, &name);
-            return true;
-        }
-    };
-
-    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) );
-    }
-    if (mTexture.image != EGL_NO_IMAGE_KHR) {
-        EGLDisplay dpy(mLayer.mFlinger->graphicPlane(0).getEGLDisplay());
-        eglDestroyImageKHR(dpy, mTexture.image);
-    }
-}
-
-void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
-{    
-    ISurface::BufferHeap buffers;
-    { // scope for the lock
-        Mutex::Autolock _l(mBufferSourceLock);
-        buffers = mBufferHeap;
-        if (buffers.heap != 0) {
-            const size_t memorySize = buffers.heap->getSize();
-            if ((size_t(offset) + mBufferSize) > memorySize) {
-                LOGE("LayerBuffer::BufferSource::postBuffer() "
-                     "invalid buffer (offset=%d, size=%d, heap-size=%d",
-                     int(offset), int(mBufferSize), int(memorySize));
-                return;
-            }
-        }
-    }
-
-    sp<Buffer> buffer;
-    if (buffers.heap != 0) {
-        buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
-        if (buffer->getStatus() != NO_ERROR)
-            buffer.clear();
-        setBuffer(buffer);
-        mLayer.invalidate();
-    }
-}
-
-void LayerBuffer::BufferSource::unregisterBuffers()
-{
-    Mutex::Autolock _l(mBufferSourceLock);
-    mBufferHeap.heap.clear();
-    mBuffer.clear();
-    mLayer.invalidate();
-}
-
-sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
-{
-    Mutex::Autolock _l(mBufferSourceLock);
-    return mBuffer;
-}
-
-void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
-{
-    Mutex::Autolock _l(mBufferSourceLock);
-    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());
-    if (UNLIKELY(ourBuffer == 0))  {
-        // nothing to do, we don't have a buffer
-        mLayer.clearWithOpenGL(clip);
-        return;
-    }
-
-    status_t err = NO_ERROR;
-    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) {
-        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
-                err = initTempBuffer();
-                if (err == NO_ERROR) {
-                    // NOTE: Assume the buffer is allocated with the proper USAGE flags
-                    const NativeBuffer& dst(mTempBuffer);
-                    region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b)));
-                    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
-                    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
-                    copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
-                    err = copybit->stretch(copybit, &dst.img, &src.img,
-                            &dst.crop, &src.crop, &clip);
-                    if (err != NO_ERROR) {
-                        clearTempBufferImage();
-                    }
-                }
-            }
-        }
-    }
-#endif
-    else {
-        err = INVALID_OPERATION;
-    }
-
-    if (err != NO_ERROR) {
-        // slower fallback
-        GGLSurface t;
-        t.version = sizeof(GGLSurface);
-        t.width  = src.crop.r;
-        t.height = src.crop.b;
-        t.stride = src.img.w;
-        t.vstride= src.img.h;
-        t.format = src.img.format;
-        t.data = (GGLubyte*)src.img.base;
-        const Region dirty(Rect(t.width, t.height));
-        mLayer.loadTexture(&mTexture, dirty, t);
-    }
-
-    mTexture.transform = mBufferHeap.transform;
-    mLayer.drawWithOpenGL(clip, mTexture);
-}
-
-status_t LayerBuffer::BufferSource::initTempBuffer() const
-{
-    // figure out the size we need now
-    const ISurface::BufferHeap& buffers(mBufferHeap);
-    uint32_t w = mLayer.mTransformedBounds.width();
-    uint32_t h = mLayer.mTransformedBounds.height();
-    if (buffers.w * h != buffers.h * w) {
-        int t = w; w = h; h = t;
-    }
-
-    // we're in the copybit case, so make sure we can handle this blit
-    // we don't have to keep the aspect ratio here
-    copybit_device_t* copybit = mLayer.mBlitEngine;
-    const int down = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
-    const int up = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
-    if (buffers.w > w*down)     w = buffers.w / down;
-    else if (w > buffers.w*up)  w = buffers.w*up;
-    if (buffers.h > h*down)     h = buffers.h / down;
-    else if (h > buffers.h*up)  h = buffers.h*up;
-
-    if (mTexture.image != EGL_NO_IMAGE_KHR) {
-        // we have an EGLImage, make sure the needed size didn't change
-        if (w!=mTexture.width || h!= mTexture.height) {
-            // delete the EGLImage and texture
-            clearTempBufferImage();
-        } else {
-            // we're good, we have an EGLImageKHR and it's (still) the
-            // right size
-            return NO_ERROR;
-        }
-    }
-
-    // figure out if we need linear filtering
-    if (buffers.w * h == buffers.h * w) {
-        // same pixel area, don't use filtering
-        mLayer.mUseLinearFiltering = false;
-    }
-
-    // Allocate a temporary buffer and create the corresponding EGLImageKHR
-    // once the EGLImage has been created we don't need the
-    // graphic buffer reference anymore.
-    sp<GraphicBuffer> buffer = new GraphicBuffer(
-            w, h, HAL_PIXEL_FORMAT_RGB_565,
-            GraphicBuffer::USAGE_HW_TEXTURE |
-            GraphicBuffer::USAGE_HW_2D);
-
-    status_t err = buffer->initCheck();
-    if (err == NO_ERROR) {
-        NativeBuffer& dst(mTempBuffer);
-        dst.img.w = buffer->getStride();
-        dst.img.h = h;
-        dst.img.format = buffer->getPixelFormat();
-        dst.img.handle = (native_handle_t *)buffer->handle;
-        dst.img.base = 0;
-        dst.crop.l = 0;
-        dst.crop.t = 0;
-        dst.crop.r = w;
-        dst.crop.b = h;
-
-        err = mLayer.initializeEglImage(buffer, &mTexture);
-    }
-
-    return err;
-}
-
-void LayerBuffer::BufferSource::clearTempBufferImage() const
-{
-    // delete the image
-    EGLDisplay dpy(mLayer.mFlinger->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();
-}
-
-// ---------------------------------------------------------------------------
-
-LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
-        sp<OverlayRef>* overlayRef, 
-        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
-    : Source(layer), mVisibilityChanged(false),
-    mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation)
-{
-    overlay_control_device_t* overlay_dev = mLayer.mFlinger->getOverlayEngine();
-    if (overlay_dev == NULL) {
-        // overlays not supported
-        return;
-    }
-
-    mOverlayDevice = overlay_dev;
-    overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
-    if (overlay == NULL) {
-        // couldn't create the overlay (no memory? no more overlays?)
-        return;
-    }
-
-    // enable dithering...
-    overlay_dev->setParameter(overlay_dev, overlay, 
-            OVERLAY_DITHER, OVERLAY_ENABLE);
-
-    mOverlay = overlay;
-    mWidth = overlay->w;
-    mHeight = overlay->h;
-    mFormat = overlay->format; 
-    mWidthStride = overlay->w_stride;
-    mHeightStride = overlay->h_stride;
-    mInitialized = false;
-
-    mOverlayHandle = overlay->getHandleRef(overlay);
-    
-    sp<OverlayChannel> channel = new OverlayChannel( &layer );
-
-    *overlayRef = new OverlayRef(mOverlayHandle, channel,
-            mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
-    mLayer.mFlinger->signalEvent();
-}
-
-LayerBuffer::OverlaySource::~OverlaySource()
-{
-    if (mOverlay && mOverlayDevice) {
-        overlay_control_device_t* overlay_dev = mOverlayDevice;
-        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
-    }
-}
-
-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;
-    mLayer.clearWithOpenGL(clip, red, green, blue, 0);
-}
-
-void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
-{
-    const Layer::State& front(mLayer.drawingState());
-    const Layer::State& temp(mLayer.currentState());
-    if (temp.sequence != front.sequence) {
-        mVisibilityChanged = true;
-    }
-}
-
-void LayerBuffer::OverlaySource::onVisibilityResolved(
-        const Transform& planeTransform)
-{
-    // this code-path must be as tight as possible, it's called each time
-    // the screen is composited.
-    if (UNLIKELY(mOverlay != 0)) {
-        if (mVisibilityChanged || !mInitialized) {
-            mVisibilityChanged = false;
-            mInitialized = true;
-            const Rect bounds(mLayer.getTransformedBounds());
-            int x = bounds.left;
-            int y = bounds.top;
-            int w = bounds.width();
-            int h = bounds.height();
-            
-            // we need a lock here to protect "destroy"
-            Mutex::Autolock _l(mOverlaySourceLock);
-            if (mOverlay) {
-                overlay_control_device_t* overlay_dev = mOverlayDevice;
-                overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
-                // we need to combine the layer orientation and the
-                // user-requested orientation.
-                Transform finalTransform = Transform(mOrientation) *
-                        Transform(mLayer.getOrientation());
-                overlay_dev->setParameter(overlay_dev, mOverlay,
-                        OVERLAY_TRANSFORM, finalTransform.getOrientation());
-                overlay_dev->commit(overlay_dev, mOverlay);
-            }
-        }
-    }
-}
-
-void LayerBuffer::OverlaySource::destroy()
-{
-    // we need a lock here to protect "onVisibilityResolved"
-    Mutex::Autolock _l(mOverlaySourceLock);
-    if (mOverlay && mOverlayDevice) {
-        overlay_control_device_t* overlay_dev = mOverlayDevice;
-        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
-        mOverlay = 0;
-    }
-}
-
-// ---------------------------------------------------------------------------
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerBuffer.h b/libs/surfaceflinger/LayerBuffer.h
deleted file mode 100644
index b176623..0000000
--- a/libs/surfaceflinger/LayerBuffer.h
+++ /dev/null
@@ -1,225 +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_LAYER_BUFFER_H
-#define ANDROID_LAYER_BUFFER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include "LayerBase.h"
-
-struct copybit_device_t;
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class Buffer;
-class Region;
-class OverlayRef;
-
-// ---------------------------------------------------------------------------
-
-class LayerBuffer : public LayerBaseClient
-{
-    class Source : public LightRefBase<Source> {
-    public:
-        Source(LayerBuffer& layer);
-        virtual ~Source();
-        virtual void onDraw(const Region& clip) const;
-        virtual void onTransaction(uint32_t flags);
-        virtual void onVisibilityResolved(const Transform& planeTransform);
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        virtual bool transformed() const;
-        virtual void destroy() { }
-    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);
-        virtual ~LayerBuffer();
-
-    virtual void onFirstRef();
-    virtual bool needsBlending() const;
-
-    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);
-    void unregisterBuffers();
-    sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format,
-            int32_t orientation);
-    
-    sp<Source> getSource() const;
-    sp<Source> clearSource();
-    void setNeedsBlending(bool blending);
-    Rect getTransformedBounds() const {
-        return mTransformedBounds;
-    }
-
-    void serverDestroy();
-
-private:
-    struct NativeBuffer {
-        copybit_image_t   img;
-        copybit_rect_t    crop;
-    };
-
-    static gralloc_module_t const* sGrallocModule;
-    static gralloc_module_t const* getGrallocModule() {
-        return sGrallocModule;
-    }
-
-    class Buffer : public LightRefBase<Buffer> {
-    public:
-        Buffer(const ISurface::BufferHeap& buffers,
-                ssize_t offset, size_t bufferSize);
-        inline bool supportsCopybit() const {
-            return mSupportsCopybit;
-        }
-        inline status_t getStatus() const {
-            return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
-        }
-        inline const NativeBuffer& getBuffer() const {
-            return mNativeBuffer;
-        }
-    protected:
-        friend class LightRefBase<Buffer>;
-        Buffer& operator = (const Buffer& rhs);
-        Buffer(const Buffer& rhs);
-        ~Buffer();
-    private:
-        ISurface::BufferHeap    mBufferHeap;
-        NativeBuffer            mNativeBuffer;
-        bool                    mSupportsCopybit;
-    };
-
-    class BufferSource : public Source {
-    public:
-        BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
-        virtual ~BufferSource();
-
-        status_t getStatus() const { return mStatus; }
-        sp<Buffer> getBuffer() const;
-        void setBuffer(const sp<Buffer>& buffer);
-
-        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;
-        void clearTempBufferImage() const;
-        mutable Mutex                   mBufferSourceLock;
-        sp<Buffer>                      mBuffer;
-        status_t                        mStatus;
-        ISurface::BufferHeap            mBufferHeap;
-        size_t                          mBufferSize;
-        mutable LayerBase::Texture      mTexture;
-        mutable NativeBuffer            mTempBuffer;
-        mutable bool                    mUseEGLImageDirectly;
-    };
-    
-    class OverlaySource : public Source {
-    public:
-        OverlaySource(LayerBuffer& layer,
-                sp<OverlayRef>* overlayRef, 
-                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
-        virtual ~OverlaySource();
-        virtual void onDraw(const Region& clip) const;
-        virtual void onTransaction(uint32_t flags);
-        virtual void onVisibilityResolved(const Transform& planeTransform);
-        virtual void destroy();
-    private:
-
-        class OverlayChannel : public BnOverlay {
-            wp<LayerBuffer> mLayer;
-            virtual void destroy() {
-                sp<LayerBuffer> layer(mLayer.promote());
-                if (layer != 0) {
-                    layer->serverDestroy();
-                }
-            }
-        public:
-            OverlayChannel(const sp<LayerBuffer>& layer)
-                : mLayer(layer) {
-            }
-        };
-        
-        friend class OverlayChannel;
-        bool mVisibilityChanged;
-
-        overlay_t* mOverlay;        
-        overlay_handle_t mOverlayHandle;
-        overlay_control_device_t* mOverlayDevice;
-        uint32_t mWidth;
-        uint32_t mHeight;
-        int32_t mFormat;
-        int32_t mWidthStride;
-        int32_t mHeightStride;
-        int32_t mOrientation;
-        mutable Mutex mOverlaySourceLock;
-        bool mInitialized;
-    };
-
-
-    class SurfaceLayerBuffer : public LayerBaseClient::Surface
-    {
-    public:
-        SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
-                        SurfaceID id, const sp<LayerBuffer>& owner);
-        virtual ~SurfaceLayerBuffer();
-
-        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
-        virtual void postBuffer(ssize_t offset);
-        virtual void unregisterBuffers();
-        
-        virtual sp<OverlayRef> createOverlay(
-                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
-    private:
-        sp<LayerBuffer> getOwner() const {
-            return static_cast<LayerBuffer*>(Surface::getOwner().get());
-        }
-    };
-
-    mutable Mutex   mLock;
-    sp<Source>      mSource;
-    sp<Surface>     mSurface;
-    bool            mInvalidate;
-    bool            mNeedsBlending;
-    copybit_device_t* mBlitEngine;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_BUFFER_H
diff --git a/libs/surfaceflinger/LayerDim.cpp b/libs/surfaceflinger/LayerDim.cpp
deleted file mode 100644
index fd61e30..0000000
--- a/libs/surfaceflinger/LayerDim.cpp
+++ /dev/null
@@ -1,168 +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 <stdlib.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/Log.h>
-
-#include <ui/GraphicBuffer.h>
-
-#include "LayerDim.h"
-#include "SurfaceFlinger.h"
-#include "DisplayHardware/DisplayHardware.h"
-
-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;
-int32_t LayerDim::sWidth;
-int32_t LayerDim::sHeight;
-
-// ---------------------------------------------------------------------------
-
-LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
-        const sp<Client>& client, int32_t i)
-    : LayerBaseClient(flinger, display, client, i)
-{
-}
-
-void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
-{
-    sTexId = -1;
-    sImage = EGL_NO_IMAGE_KHR;
-    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()
-{
-}
-
-void LayerDim::onDraw(const Region& clip) const
-{
-    const State& s(drawingState());
-    Region::const_iterator it = clip.begin();
-    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 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);
-        }
-
-        GLshort w = sWidth;
-        GLshort h = sHeight;
-        const GLshort vertices[4][2] = {
-                { 0, 0 },
-                { 0, h },
-                { w, h },
-                { w, 0 }
-        };
-        glVertexPointer(2, GL_SHORT, 0, vertices);
-
-        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);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/LayerDim.h b/libs/surfaceflinger/LayerDim.h
deleted file mode 100644
index d4672a1..0000000
--- a/libs/surfaceflinger/LayerDim.h
+++ /dev/null
@@ -1,60 +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_LAYER_DIM_H
-#define ANDROID_LAYER_DIM_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <EGL/egl.h>
-#include <EGL/eglext.h>
-
-#include "LayerBase.h"
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-class LayerDim : public LayerBaseClient
-{
-    static bool sUseTexture;
-    static GLuint sTexId;
-    static EGLImageKHR sImage;
-    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);
-        virtual ~LayerDim();
-
-    virtual void onDraw(const Region& clip) const;
-    virtual bool needsBlending() const  { return true; }
-    virtual bool isSecure() const       { return false; }
-
-    static void initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h);
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_LAYER_DIM_H
diff --git a/libs/surfaceflinger/MessageQueue.cpp b/libs/surfaceflinger/MessageQueue.cpp
deleted file mode 100644
index b43d801..0000000
--- a/libs/surfaceflinger/MessageQueue.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 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 <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/Log.h>
-#include <binder/IPCThreadState.h>
-
-#include "MessageQueue.h"
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-void MessageList::insert(const sp<MessageBase>& node) 
-{
-    LIST::iterator cur(mList.begin());
-    LIST::iterator end(mList.end());
-    while (cur != end) {
-        if (*node < **cur) {
-            mList.insert(cur, node);
-            return;
-        }
-        ++cur;
-    }
-    mList.insert(++end, node);
-}
-
-void MessageList::remove(MessageList::LIST::iterator pos) 
-{
-    mList.erase(pos);
-}
-
-// ---------------------------------------------------------------------------
-
-MessageQueue::MessageQueue()
-    : mInvalidate(false)
-{
-    mInvalidateMessage = new MessageBase(INVALIDATE);
-}
-
-MessageQueue::~MessageQueue()
-{
-}
-
-MessageList::value_type MessageQueue::waitMessage(nsecs_t timeout)
-{
-    MessageList::value_type result;
-
-    bool again;
-    do {
-        const nsecs_t timeoutTime = systemTime() + timeout;
-        while (true) {
-            Mutex::Autolock _l(mLock);
-            nsecs_t now = systemTime();
-            nsecs_t nextEventTime = -1;
-
-            // invalidate messages are always handled first
-            if (mInvalidate) {
-                mInvalidate = false;
-                mInvalidateMessage->when = now;
-                result = mInvalidateMessage;
-                break;
-            }
-
-            LIST::iterator cur(mMessages.begin());
-            if (cur != mMessages.end()) {
-                result = *cur;
-            }
-            
-            if (result != 0) {
-                if (result->when <= now) {
-                    // there is a message to deliver
-                    mMessages.remove(cur);
-                    break;
-                }
-                if (timeout>=0 && timeoutTime < now) {
-                    // we timed-out, return a NULL message
-                    result = 0;
-                    break;
-                }
-                nextEventTime = result->when;
-                result = 0;
-            }
-
-            if (timeout >= 0 && nextEventTime > 0) {
-                if (nextEventTime > timeoutTime) {
-                    nextEventTime = timeoutTime;
-                }
-            }
-
-            if (nextEventTime >= 0) {
-                //LOGD("nextEventTime = %lld ms", nextEventTime);
-                if (nextEventTime > 0) {
-                    // we're about to wait, flush the binder command buffer
-                    IPCThreadState::self()->flushCommands();
-                    const nsecs_t reltime = nextEventTime - systemTime();
-                    if (reltime > 0) {
-                        mCondition.waitRelative(mLock, reltime);
-                    }
-                }
-            } else {
-                //LOGD("going to wait");
-                // we're about to wait, flush the binder command buffer
-                IPCThreadState::self()->flushCommands();
-                mCondition.wait(mLock);
-            }
-        } 
-        // here we're not holding the lock anymore
-
-        if (result == 0)
-            break;
-
-        again = result->handler();
-        if (again) {
-            // the message has been processed. release our reference to it
-            // without holding the lock.
-            result = 0;
-        }
-        
-    } while (again);
-
-    return result;
-}
-
-status_t MessageQueue::postMessage(
-        const MessageList::value_type& message, nsecs_t relTime, uint32_t flags)
-{
-    return queueMessage(message, relTime, flags);
-}
-
-status_t MessageQueue::invalidate() {
-    Mutex::Autolock _l(mLock);
-    mInvalidate = true;
-    mCondition.signal();
-    return NO_ERROR;
-}
-
-status_t MessageQueue::queueMessage(
-        const MessageList::value_type& message, nsecs_t relTime, uint32_t flags)
-{
-    Mutex::Autolock _l(mLock);
-    message->when = systemTime() + relTime;
-    mMessages.insert(message);
-    
-    //LOGD("MessageQueue::queueMessage time = %lld ms", message->when);
-    //dumpLocked(message);
-
-    mCondition.signal();
-    return NO_ERROR;
-}
-
-void MessageQueue::dump(const MessageList::value_type& message)
-{
-    Mutex::Autolock _l(mLock);
-    dumpLocked(message);
-}
-
-void MessageQueue::dumpLocked(const MessageList::value_type& message)
-{
-    LIST::const_iterator cur(mMessages.begin());
-    LIST::const_iterator end(mMessages.end());
-    int c = 0;
-    while (cur != end) {
-        const char tick = (*cur == message) ? '>' : ' ';
-        LOGD("%c %d: msg{.what=%08x, when=%lld}",
-                tick, c, (*cur)->what, (*cur)->when);
-        ++cur;
-        c++;
-    }
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/MessageQueue.h b/libs/surfaceflinger/MessageQueue.h
deleted file mode 100644
index dc8138d..0000000
--- a/libs/surfaceflinger/MessageQueue.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 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_MESSAGE_QUEUE_H
-#define ANDROID_MESSAGE_QUEUE_H
-
-#include <stdint.h>
-#include <errno.h>
-#include <sys/types.h>
-
-#include <utils/threads.h>
-#include <utils/Timers.h>
-#include <utils/List.h>
-
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-class MessageBase;
-
-class MessageList 
-{
-    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(); }
-    inline LIST::const_iterator end() const      { return mList.end(); }
-    inline bool isEmpty() const { return mList.empty(); }
-    void insert(const sp<MessageBase>& node);
-    void remove(LIST::iterator pos);
-};
-
-// ============================================================================
-
-class MessageBase : 
-    public LightRefBase<MessageBase>
-{
-public:
-    nsecs_t     when;
-    uint32_t    what;
-    int32_t     arg0;    
-
-    MessageBase() : when(0), what(0), arg0(0) { }
-    MessageBase(uint32_t what, int32_t arg0=0)
-        : when(0), what(what), arg0(arg0) { }
-    
-    // return true if message has a handler
-    virtual bool handler() { return false; }
-    
-protected:
-    virtual ~MessageBase() { }
-
-private:
-    friend class LightRefBase<MessageBase>;
-};
-
-inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) {
-    return lhs.when < rhs.when;
-}
-
-// ---------------------------------------------------------------------------
-
-class MessageQueue
-{
-    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
-    };
-
-    MessageList::value_type waitMessage(nsecs_t timeout = -1);
-    
-    status_t postMessage(const MessageList::value_type& message, 
-            nsecs_t reltime=0, uint32_t flags = 0);
-        
-    status_t invalidate();
-    
-    void dump(const MessageList::value_type& message);
-
-private:
-    status_t queueMessage(const MessageList::value_type& message,
-            nsecs_t reltime, uint32_t flags);
-    void dumpLocked(const MessageList::value_type& message);
-    
-    Mutex           mLock;
-    Condition       mCondition;
-    MessageList     mMessages;
-    bool            mInvalidate;
-    MessageList::value_type mInvalidateMessage;
-};
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif /* ANDROID_MESSAGE_QUEUE_H */
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
deleted file mode 100644
index 0722fda..0000000
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ /dev/null
@@ -1,1940 +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 <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <math.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-
-#include <cutils/log.h>
-#include <cutils/properties.h>
-
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/MemoryHeapBase.h>
-
-#include <utils/String8.h>
-#include <utils/String16.h>
-#include <utils/StopWatch.h>
-
-#include <ui/GraphicBufferAllocator.h>
-#include <ui/PixelFormat.h>
-
-#include <pixelflinger/pixelflinger.h>
-#include <GLES/gl.h>
-
-#include "clz.h"
-#include "Layer.h"
-#include "LayerBlur.h"
-#include "LayerBuffer.h"
-#include "LayerDim.h"
-#include "SurfaceFlinger.h"
-
-#include "DisplayHardware/DisplayHardware.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 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),
-        mTransactionCount(0),
-        mResizeTransationPending(false),
-        mLayersRemoved(false),
-        mBootTime(systemTime()),
-        mHardwareTest("android.permission.HARDWARE_TEST"),
-        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
-        mDump("android.permission.DUMP"),
-        mVisibleRegionsDirty(false),
-        mDeferReleaseConsole(false),
-        mFreezeDisplay(false),
-        mFreezeCount(0),
-        mFreezeDisplayTime(0),
-        mDebugRegion(0),
-        mDebugBackground(0),
-        mDebugInSwapBuffers(0),
-        mLastSwapBufferTime(0),
-        mDebugInTransaction(0),
-        mLastTransactionTime(0),
-        mBootFinished(false),
-        mConsoleSignals(0),
-        mSecureFrameBuffer(0)
-{
-    init();
-}
-
-void SurfaceFlinger::init()
-{
-    LOGI("SurfaceFlinger is starting");
-
-    // debugging stuff...
-    char value[PROPERTY_VALUE_MAX];
-    property_get("debug.sf.showupdates", value, "0");
-    mDebugRegion = atoi(value);
-    property_get("debug.sf.showbackground", value, "0");
-    mDebugBackground = atoi(value);
-
-    LOGI_IF(mDebugRegion,           "showupdates enabled");
-    LOGI_IF(mDebugBackground,       "showbackground enabled");
-}
-
-SurfaceFlinger::~SurfaceFlinger()
-{
-    glDeleteTextures(1, &mWormholeTexName);
-}
-
-overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
-{
-    return graphicPlane(0).displayHardware().getOverlayEngine();
-}
-
-sp<IMemoryHeap> SurfaceFlinger::getCblk() const
-{
-    return mServerHeap;
-}
-
-sp<ISurfaceFlingerClient> 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;
-    }
-    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)
-{
-    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);
-    }
-}
-
-const GraphicPlane& SurfaceFlinger::graphicPlane(int dpy) const
-{
-    LOGE_IF(uint32_t(dpy) >= DISPLAY_COUNT, "Invalid DisplayID %d", dpy);
-    const GraphicPlane& plane(mGraphicPlanes[dpy]);
-    return plane;
-}
-
-GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
-{
-    return const_cast<GraphicPlane&>(
-        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
-}
-
-void SurfaceFlinger::bootFinished()
-{
-    const nsecs_t now = systemTime();
-    const nsecs_t duration = now - mBootTime;
-    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );  
-    mBootFinished = true;
-    property_set("ctl.stop", "bootanim");
-}
-
-void SurfaceFlinger::onFirstRef()
-{
-    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
-
-    // Wait for the main thread to be done with its initialization
-    mReadyToRunBarrier.wait();
-}
-
-static inline uint16_t pack565(int r, int g, int b) {
-    return (r<<11)|(g<<5)|b;
-}
-
-status_t SurfaceFlinger::readyToRun()
-{
-    LOGI(   "SurfaceFlinger's main thread ready to run. "
-            "Initializing graphics H/W...");
-
-    // we only support one display currently
-    int dpy = 0;
-
-    {
-        // initialize the main display
-        GraphicPlane& plane(graphicPlane(dpy));
-        DisplayHardware* const hw = new DisplayHardware(this, dpy);
-        plane.setDisplayHardware(hw);
-    }
-
-    // create the shared control-block
-    mServerHeap = new MemoryHeapBase(4096,
-            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
-    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
-    
-    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
-    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
-    
-    new(mServerCblk) surface_flinger_cblk_t;
-
-    // initialize primary screen
-    // (other display should be initialized in the same manner, but
-    // asynchronously, as they could come and go. None of this is supported
-    // yet).
-    const GraphicPlane& plane(graphicPlane(dpy));
-    const DisplayHardware& hw = plane.displayHardware();
-    const uint32_t w = hw.getWidth();
-    const uint32_t h = hw.getHeight();
-    const uint32_t f = hw.getFormat();
-    hw.makeCurrent();
-
-    // initialize the shared control block
-    mServerCblk->connected |= 1<<dpy;
-    display_cblk_t* dcblk = mServerCblk->displays + dpy;
-    memset(dcblk, 0, sizeof(display_cblk_t));
-    dcblk->w            = plane.getWidth();
-    dcblk->h            = plane.getHeight();
-    dcblk->format       = f;
-    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
-    dcblk->xdpi         = hw.getDpiX();
-    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);
-    glEnable(GL_SCISSOR_TEST);
-    glShadeModel(GL_FLAT);
-    glDisable(GL_DITHER);
-    glDisable(GL_CULL_FACE);
-
-    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
-    const uint16_t g1 = pack565(0x17,0x2f,0x17);
-    const uint16_t textureData[4] = { g0, g1, g1, g0 };
-    glGenTextures(1, &mWormholeTexName);
-    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
-    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
-            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
-
-    glViewport(0, 0, w, h);
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    glOrthof(0, w, h, 0, 0, 1);
-
-   LayerDim::initDimmer(this, w, h);
-
-    mReadyToRunBarrier.open();
-
-    /*
-     *  We're now ready to accept clients...
-     */
-
-    // start boot animation
-    property_set("ctl.start", "bootanim");
-    
-    return NO_ERROR;
-}
-
-// ----------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#pragma mark Events Handler
-#endif
-
-void SurfaceFlinger::waitForEvent()
-{
-    while (true) {
-        nsecs_t timeout = -1;
-        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
-        if (UNLIKELY(isFrozen())) {
-            // wait 5 seconds
-            const nsecs_t now = systemTime();
-            if (mFreezeDisplayTime == 0) {
-                mFreezeDisplayTime = now;
-            }
-            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
-            timeout = waitTime>0 ? waitTime : 0;
-        }
-
-        MessageList::value_type msg = mEventQueue.waitMessage(timeout);
-
-        // see if we timed out
-        if (isFrozen()) {
-            const nsecs_t now = systemTime();
-            nsecs_t frozenTime = (now - mFreezeDisplayTime);
-            if (frozenTime >= freezeDisplayTimeout) {
-                // we timed out and are still frozen
-                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
-                        mFreezeDisplay, mFreezeCount);
-                mFreezeDisplayTime = 0;
-                mFreezeCount = 0;
-                mFreezeDisplay = false;
-            }
-        }
-
-        if (msg != 0) {
-            switch (msg->what) {
-                case MessageQueue::INVALIDATE:
-                    // invalidate message, just return to the main loop
-                    return;
-            }
-        }
-    }
-}
-
-void SurfaceFlinger::signalEvent() {
-    mEventQueue.invalidate();
-}
-
-void SurfaceFlinger::signal() const {
-    // this is the IPC call
-    const_cast<SurfaceFlinger*>(this)->signalEvent();
-}
-
-void SurfaceFlinger::signalDelayedEvent(nsecs_t delay)
-{
-    mEventQueue.postMessage( new MessageBase(MessageQueue::INVALIDATE), delay);
-}
-
-// ----------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#pragma mark Main loop
-#endif
-
-bool SurfaceFlinger::threadLoop()
-{
-    waitForEvent();
-
-    // check for transactions
-    if (UNLIKELY(mConsoleSignals)) {
-        handleConsoleEvents();
-    }
-
-    if (LIKELY(mTransactionCount == 0)) {
-        // if we're in a global transaction, don't do anything.
-        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
-        uint32_t transactionFlags = getTransactionFlags(mask);
-        if (LIKELY(transactionFlags)) {
-            handleTransaction(transactionFlags);
-        }
-    }
-
-    // post surfaces (if needed)
-    handlePageFlip();
-
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    if (LIKELY(hw.canDraw() && !isFrozen())) {
-        // repaint the framebuffer (if needed)
-        handleRepaint();
-
-        // inform the h/w that we're done compositing
-        hw.compositionComplete();
-
-        // release the clients before we flip ('cause flip might block)
-        unlockClients();
-
-        postFramebuffer();
-    } else {
-        // pretend we did the post
-        unlockClients();
-        usleep(16667); // 60 fps period
-    }
-    return true;
-}
-
-void SurfaceFlinger::postFramebuffer()
-{
-    if (!mInvalidRegion.isEmpty()) {
-        const DisplayHardware& hw(graphicPlane(0).displayHardware());
-        const nsecs_t now = systemTime();
-        mDebugInSwapBuffers = now;
-        hw.flip(mInvalidRegion);
-        mLastSwapBufferTime = systemTime() - now;
-        mDebugInSwapBuffers = 0;
-        mInvalidRegion.clear();
-    }
-}
-
-void SurfaceFlinger::handleConsoleEvents()
-{
-    // something to do with the console
-    const DisplayHardware& hw = graphicPlane(0).displayHardware();
-
-    int what = android_atomic_and(0, &mConsoleSignals);
-    if (what & eConsoleAcquired) {
-        hw.acquireScreen();
-    }
-
-    if (mDeferReleaseConsole && hw.canDraw()) {
-        // We got the release signal before the acquire signal
-        mDeferReleaseConsole = false;
-        hw.releaseScreen();
-    }
-
-    if (what & eConsoleReleased) {
-        if (hw.canDraw()) {
-            hw.releaseScreen();
-        } else {
-            mDeferReleaseConsole = true;
-        }
-    }
-
-    mDirtyRegion.set(hw.bounds());
-}
-
-void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
-{
-    Vector< sp<LayerBase> > ditchedLayers;
-
-    { // scope for the lock
-        Mutex::Autolock _l(mStateLock);
-        const nsecs_t now = systemTime();
-        mDebugInTransaction = now;
-        handleTransactionLocked(transactionFlags, ditchedLayers);
-        mLastTransactionTime = systemTime() - now;
-        mDebugInTransaction = 0;
-    }
-
-    // do this without lock held
-    const size_t count = ditchedLayers.size();
-    for (size_t i=0 ; i<count ; i++) {
-        if (ditchedLayers[i] != 0) {
-            //LOGD("ditching layer %p", ditchedLayers[i].get());
-            ditchedLayers[i]->ditch();
-        }
-    }
-}
-
-void SurfaceFlinger::handleTransactionLocked(
-        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
-{
-    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
-    const size_t count = currentLayers.size();
-
-    /*
-     * Traversal of the children
-     * (perform the transaction for each of them if needed)
-     */
-
-    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
-    if (layersNeedTransaction) {
-        for (size_t i=0 ; i<count ; i++) {
-            const sp<LayerBase>& layer = currentLayers[i];
-            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
-            if (!trFlags) continue;
-
-            const uint32_t flags = layer->doTransaction(0);
-            if (flags & Layer::eVisibleRegion)
-                mVisibleRegionsDirty = true;
-        }
-    }
-
-    /*
-     * Perform our own transaction if needed
-     */
-
-    if (transactionFlags & eTransactionNeeded) {
-        if (mCurrentState.orientation != mDrawingState.orientation) {
-            // the orientation has changed, recompute all visible regions
-            // and invalidate everything.
-
-            const int dpy = 0;
-            const int orientation = mCurrentState.orientation;
-            const uint32_t type = mCurrentState.orientationType;
-            GraphicPlane& plane(graphicPlane(dpy));
-            plane.setOrientation(orientation);
-
-            // update the shared control block
-            const DisplayHardware& hw(plane.displayHardware());
-            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
-            dcblk->orientation = orientation;
-            dcblk->w = plane.getWidth();
-            dcblk->h = plane.getHeight();
-
-            mVisibleRegionsDirty = true;
-            mDirtyRegion.set(hw.bounds());
-        }
-
-        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
-            // freezing or unfreezing the display -> trigger animation if needed
-            mFreezeDisplay = mCurrentState.freezeDisplay;
-            if (mFreezeDisplay)
-                 mFreezeDisplayTime = 0;
-        }
-
-        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
-            // layers have been added
-            mVisibleRegionsDirty = true;
-        }
-
-        // some layers might have been removed, so
-        // we need to update the regions they're exposing.
-        if (mLayersRemoved) {
-            mLayersRemoved = false;
-            mVisibleRegionsDirty = true;
-            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
-            const size_t count = previousLayers.size();
-            for (size_t i=0 ; i<count ; i++) {
-                const sp<LayerBase>& layer(previousLayers[i]);
-                if (currentLayers.indexOf( layer ) < 0) {
-                    // this layer is not visible anymore
-                    ditchedLayers.add(layer);
-                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
-                }
-            }
-        }
-
-        // get rid of all resources we don't need anymore
-        // (layers and clients)
-        free_resources_l();
-    }
-
-    commitTransaction();
-}
-
-sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
-{
-    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
-}
-
-void SurfaceFlinger::computeVisibleRegions(
-    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
-{
-    const GraphicPlane& plane(graphicPlane(0));
-    const Transform& planeTransform(plane.transform());
-    const DisplayHardware& hw(plane.displayHardware());
-    const Region screenRegion(hw.bounds());
-
-    Region aboveOpaqueLayers;
-    Region aboveCoveredLayers;
-    Region dirty;
-
-    bool secureFrameBuffer = false;
-
-    size_t i = currentLayers.size();
-    while (i--) {
-        const sp<LayerBase>& layer = currentLayers[i];
-        layer->validateVisibility(planeTransform);
-
-        // start with the whole surface at its current location
-        const Layer::State& s(layer->drawingState());
-
-        /*
-         * opaqueRegion: area of a surface that is fully opaque.
-         */
-        Region opaqueRegion;
-
-        /*
-         * visibleRegion: area of a surface that is visible on screen
-         * and not fully transparent. This is essentially the layer's
-         * footprint minus the opaque regions above it.
-         * Areas covered by a translucent surface are considered visible.
-         */
-        Region visibleRegion;
-
-        /*
-         * coveredRegion: area of a surface that is covered by all
-         * visible regions above it (which includes the translucent areas).
-         */
-        Region coveredRegion;
-
-
-        // handle hidden surfaces by setting the visible region to empty
-        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
-            const bool translucent = layer->needsBlending();
-            const Rect bounds(layer->visibleBounds());
-            visibleRegion.set(bounds);
-            visibleRegion.andSelf(screenRegion);
-            if (!visibleRegion.isEmpty()) {
-                // Remove the transparent area from the visible region
-                if (translucent) {
-                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
-                }
-
-                // compute the opaque region
-                const int32_t layerOrientation = layer->getOrientation();
-                if (s.alpha==255 && !translucent &&
-                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
-                    // the opaque region is the layer's footprint
-                    opaqueRegion = visibleRegion;
-                }
-            }
-        }
-
-        // Clip the covered region to the visible region
-        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
-
-        // Update aboveCoveredLayers for next (lower) layer
-        aboveCoveredLayers.orSelf(visibleRegion);
-
-        // subtract the opaque region covered by the layers above us
-        visibleRegion.subtractSelf(aboveOpaqueLayers);
-
-        // compute this layer's dirty region
-        if (layer->contentDirty) {
-            // we need to invalidate the whole region
-            dirty = visibleRegion;
-            // as well, as the old visible region
-            dirty.orSelf(layer->visibleRegionScreen);
-            layer->contentDirty = false;
-        } else {
-            /* compute the exposed region:
-             *   the exposed region consists of two components:
-             *   1) what's VISIBLE now and was COVERED before
-             *   2) what's EXPOSED now less what was EXPOSED before
-             *
-             * note that (1) is conservative, we start with the whole
-             * visible region but only keep what used to be covered by
-             * something -- which mean it may have been exposed.
-             *
-             * (2) handles areas that were not covered by anything but got
-             * exposed because of a resize.
-             */
-            const Region newExposed = visibleRegion - coveredRegion;
-            const Region oldVisibleRegion = layer->visibleRegionScreen;
-            const Region oldCoveredRegion = layer->coveredRegionScreen;
-            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
-            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
-        }
-        dirty.subtractSelf(aboveOpaqueLayers);
-
-        // accumulate to the screen dirty region
-        dirtyRegion.orSelf(dirty);
-
-        // Update aboveOpaqueLayers for next (lower) layer
-        aboveOpaqueLayers.orSelf(opaqueRegion);
-        
-        // Store the visible region is screen space
-        layer->setVisibleRegion(visibleRegion);
-        layer->setCoveredRegion(coveredRegion);
-
-        // If a secure layer is partially visible, lock-down the screen!
-        if (layer->isSecure() && !visibleRegion.isEmpty()) {
-            secureFrameBuffer = true;
-        }
-    }
-
-    // invalidate the areas where a layer was removed
-    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
-    mDirtyRegionRemovedLayer.clear();
-
-    mSecureFrameBuffer = secureFrameBuffer;
-    opaqueRegion = aboveOpaqueLayers;
-}
-
-
-void SurfaceFlinger::commitTransaction()
-{
-    mDrawingState = mCurrentState;
-    mResizeTransationPending = false;
-    mTransactionCV.broadcast();
-}
-
-void SurfaceFlinger::handlePageFlip()
-{
-    bool visibleRegions = mVisibleRegionsDirty;
-    LayerVector& currentLayers = const_cast<LayerVector&>(mDrawingState.layersSortedByZ);
-    visibleRegions |= lockPageFlip(currentLayers);
-
-        const DisplayHardware& hw = graphicPlane(0).displayHardware();
-        const Region screenRegion(hw.bounds());
-        if (visibleRegions) {
-            Region opaqueRegion;
-            computeVisibleRegions(currentLayers, mDirtyRegion, opaqueRegion);
-            mWormholeRegion = screenRegion.subtract(opaqueRegion);
-            mVisibleRegionsDirty = false;
-        }
-
-    unlockPageFlip(currentLayers);
-    mDirtyRegion.andSelf(screenRegion);
-}
-
-bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
-{
-    bool recomputeVisibleRegions = false;
-    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];
-        layer->lockPageFlip(recomputeVisibleRegions);
-    }
-    return recomputeVisibleRegions;
-}
-
-void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
-{
-    const GraphicPlane& plane(graphicPlane(0));
-    const Transform& planeTransform(plane.transform());
-    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];
-        layer->unlockPageFlip(planeTransform, mDirtyRegion);
-    }
-}
-
-
-void SurfaceFlinger::handleRepaint()
-{
-    // compute the invalid region
-    mInvalidRegion.orSelf(mDirtyRegion);
-    if (mInvalidRegion.isEmpty()) {
-        // nothing to do
-        return;
-    }
-
-    if (UNLIKELY(mDebugRegion)) {
-        debugFlashRegions();
-    }
-
-    // set the frame buffer
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    glMatrixMode(GL_MODELVIEW);
-    glLoadIdentity();
-
-    uint32_t flags = hw.getFlags();
-    if ((flags & DisplayHardware::SWAP_RECTANGLE) || 
-        (flags & DisplayHardware::BUFFER_PRESERVED)) 
-    {
-        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
-        // 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
-            // SWAP_RECTANGLE so that we don't have to redraw all this.
-            mDirtyRegion.set(mInvalidRegion.bounds());
-        } else {
-            // in the BUFFER_PRESERVED case, obviously, we can update only
-            // what's needed and nothing more.
-            // NOTE: this is NOT a common case, as preserving the backbuffer
-            // is costly and usually involves copying the whole update back.
-        }
-    } else {
-        if (flags & DisplayHardware::PARTIAL_UPDATES) {
-            // We need to redraw the rectangle that will be updated
-            // (pushed to the framebuffer).
-            // This is needed because PARTIAL_UPDATES only takes one
-            // rectangle instead of a region (see DisplayHardware::flip())
-            mDirtyRegion.set(mInvalidRegion.bounds());
-        } else {
-            // we need to redraw everything (the whole screen)
-            mDirtyRegion.set(hw.bounds());
-            mInvalidRegion = mDirtyRegion;
-        }
-    }
-
-    // compose all surfaces
-    composeSurfaces(mDirtyRegion);
-
-    // clear the dirty regions
-    mDirtyRegion.clear();
-}
-
-void SurfaceFlinger::composeSurfaces(const Region& dirty)
-{
-    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
-        // should never happen unless the window manager has a bug
-        // 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();
-    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);
-            }
-        }
-    }
-}
-
-void SurfaceFlinger::unlockClients()
-{
-    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
-    const size_t count = drawingLayers.size();
-    sp<LayerBase> const* const layers = drawingLayers.array();
-    for (size_t i=0 ; i<count ; ++i) {
-        const sp<LayerBase>& layer = layers[i];
-        layer->finishPageFlip();
-    }
-}
-
-void SurfaceFlinger::debugFlashRegions()
-{
-     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);
-    glDisable(GL_BLEND);
-    glDisable(GL_DITHER);
-    glDisable(GL_SCISSOR_TEST);
-
-    static int toggle = 0;
-    toggle = 1 - toggle;
-    if (toggle) {
-        glColor4x(0x10000, 0, 0x10000, 0x10000);
-    } else {
-        glColor4x(0x10000, 0x10000, 0, 0x10000);
-    }
-
-    Region::const_iterator it = mDirtyRegion.begin();
-    Region::const_iterator const end = mDirtyRegion.end();
-    while (it != end) {
-        const Rect& r = *it++;
-        GLfloat vertices[][2] = {
-                { r.left,  r.top },
-                { r.left,  r.bottom },
-                { r.right, r.bottom },
-                { r.right, r.top }
-        };
-        glVertexPointer(2, GL_FLOAT, 0, vertices);
-        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-    }
-    
-    if (mInvalidRegion.isEmpty()) {
-        mDirtyRegion.dump("mDirtyRegion");
-        mInvalidRegion.dump("mInvalidRegion");
-    }
-    hw.flip(mInvalidRegion);
-
-    if (mDebugRegion > 1)
-       usleep(mDebugRegion * 1000);
-
-    glEnable(GL_SCISSOR_TEST);
-    //mDirtyRegion.dump("mDirtyRegion");
-}
-
-void SurfaceFlinger::drawWormhole() const
-{
-    const Region region(mWormholeRegion.intersect(mDirtyRegion));
-    if (region.isEmpty())
-        return;
-
-    const DisplayHardware& hw(graphicPlane(0).displayHardware());
-    const int32_t width = hw.getWidth();
-    const int32_t height = hw.getHeight();
-
-    glDisable(GL_BLEND);
-    glDisable(GL_DITHER);
-
-    if (LIKELY(!mDebugBackground)) {
-        glClearColorx(0,0,0,0);
-        Region::const_iterator it = region.begin();
-        Region::const_iterator const end = region.end();
-        while (it != end) {
-            const Rect& r = *it++;
-            const GLint sy = height - (r.top + r.height());
-            glScissor(r.left, sy, r.width(), r.height());
-            glClear(GL_COLOR_BUFFER_BIT);
-        }
-    } else {
-        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
-                { width, height }, { 0, height }  };
-        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
-        glVertexPointer(2, GL_SHORT, 0, vertices);
-        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
-        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-        glEnable(GL_TEXTURE_2D);
-        glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
-        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        glMatrixMode(GL_TEXTURE);
-        glLoadIdentity();
-        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
-        Region::const_iterator it = region.begin();
-        Region::const_iterator const end = region.end();
-        while (it != end) {
-            const Rect& r = *it++;
-            const GLint sy = height - (r.top + r.height());
-            glScissor(r.left, sy, r.width(), r.height());
-            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-        }
-        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-    }
-}
-
-void SurfaceFlinger::debugShowFPS() const
-{
-    static int mFrameCount;
-    static int mLastFrameCount = 0;
-    static nsecs_t mLastFpsTime = 0;
-    static float mFps = 0;
-    mFrameCount++;
-    nsecs_t now = systemTime();
-    nsecs_t diff = now - mLastFpsTime;
-    if (diff > ms2ns(250)) {
-        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
-        mLastFpsTime = now;
-        mLastFrameCount = mFrameCount;
-    }
-    // XXX: mFPS has the value we want
- }
-
-status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
-{
-    Mutex::Autolock _l(mStateLock);
-    addLayer_l(layer);
-    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::removeLayer(const sp<LayerBase>& layer)
-{
-    Mutex::Autolock _l(mStateLock);
-    status_t err = purgatorizeLayer_l(layer);
-    if (err == NO_ERROR)
-        setTransactionFlags(eTransactionNeeded);
-    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)
-{
-    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);
-}
-
-status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
-{
-    // remove the layer from the main list (through a transaction).
-    ssize_t err = removeLayer_l(layerBase);
-
-    layerBase->onRemoved();
-
-    // 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().
-    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
-}
-
-
-void SurfaceFlinger::free_resources_l()
-{
-    // 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();
-}
-
-uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
-{
-    return android_atomic_and(~flags, &mTransactionFlags) & flags;
-}
-
-uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags, nsecs_t delay)
-{
-    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
-    if ((old & flags)==0) { // wake the server up
-        if (delay > 0) {
-            signalDelayedEvent(delay);
-        } else {
-            signalEvent();
-        }
-    }
-    return old;
-}
-
-void SurfaceFlinger::openGlobalTransaction()
-{
-    android_atomic_inc(&mTransactionCount);
-}
-
-void SurfaceFlinger::closeGlobalTransaction()
-{
-    if (android_atomic_dec(&mTransactionCount) == 1) {
-        signalEvent();
-
-        // if there is a transaction with a resize, wait for it to 
-        // take effect before returning.
-        Mutex::Autolock _l(mStateLock);
-        while (mResizeTransationPending) {
-            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
-            if (CC_UNLIKELY(err != NO_ERROR)) {
-                // just in case something goes wrong in SF, return to the
-                // called after a few seconds.
-                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
-                mResizeTransationPending = false;
-                break;
-            }
-        }
-    }
-}
-
-status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
-{
-    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
-        return BAD_VALUE;
-
-    Mutex::Autolock _l(mStateLock);
-    mCurrentState.freezeDisplay = 1;
-    setTransactionFlags(eTransactionNeeded);
-
-    // flags is intended to communicate some sort of animation behavior
-    // (for instance fading)
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
-{
-    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
-        return BAD_VALUE;
-
-    Mutex::Autolock _l(mStateLock);
-    mCurrentState.freezeDisplay = 0;
-    setTransactionFlags(eTransactionNeeded);
-
-    // flags is intended to communicate some sort of animation behavior
-    // (for instance fading)
-    return NO_ERROR;
-}
-
-int SurfaceFlinger::setOrientation(DisplayID dpy, 
-        int orientation, uint32_t flags)
-{
-    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
-        return BAD_VALUE;
-
-    Mutex::Autolock _l(mStateLock);
-    if (mCurrentState.orientation != orientation) {
-        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
-            mCurrentState.orientationType = flags;
-            mCurrentState.orientation = orientation;
-            setTransactionFlags(eTransactionNeeded);
-            mTransactionCV.wait(mStateLock);
-        } else {
-            orientation = BAD_VALUE;
-        }
-    }
-    return orientation;
-}
-
-sp<ISurface> SurfaceFlinger::createSurface(ClientID clientId, int pid,
-        const String8& name, ISurfaceFlingerClient::surface_data_t* params,
-        DisplayID d, uint32_t w, uint32_t h, PixelFormat format,
-        uint32_t flags)
-{
-    sp<LayerBaseClient> layer;
-    sp<LayerBaseClient::Surface> surfaceHandle;
-
-    if (int32_t(w|h) < 0) {
-        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
-                int(w), int(h));
-        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;
-    }
-
-    switch (flags & eFXSurfaceMask) {
-        case eFXSurfaceNormal:
-            if (UNLIKELY(flags & ePushBuffers)) {
-                layer = createPushBuffersSurfaceLocked(client, d, id,
-                        w, h, flags);
-            } else {
-                layer = createNormalSurfaceLocked(client, d, id,
-                        w, h, flags, format);
-            }
-            break;
-        case eFXSurfaceBlur:
-            layer = createBlurSurfaceLocked(client, d, id, w, h, flags);
-            break;
-        case eFXSurfaceDim:
-            layer = createDimSurfaceLocked(client, d, id, w, h, flags);
-            break;
-    }
-
-    if (layer != 0) {
-        layer->setName(name);
-        setTransactionFlags(eTransactionNeeded);
-        surfaceHandle = layer->getSurface();
-        if (surfaceHandle != 0) { 
-            params->token = surfaceHandle->getToken();
-            params->identity = surfaceHandle->getIdentity();
-            params->width = w;
-            params->height = h;
-            params->format = format;
-        }
-    }
-
-    return surfaceHandle;
-}
-
-sp<LayerBaseClient> SurfaceFlinger::createNormalSurfaceLocked(
-        const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags,
-        PixelFormat& format)
-{
-    // initialize the surfaces
-    switch (format) { // TODO: take h/w into account
-    case PIXEL_FORMAT_TRANSPARENT:
-    case PIXEL_FORMAT_TRANSLUCENT:
-        format = PIXEL_FORMAT_RGBA_8888;
-        break;
-    case PIXEL_FORMAT_OPAQUE:
-        format = PIXEL_FORMAT_RGB_565;
-        break;
-    }
-
-    sp<Layer> layer = new Layer(this, display, client, id);
-    status_t err = layer->setBuffers(w, h, format, flags);
-    if (LIKELY(err == NO_ERROR)) {
-        layer->initStates(w, h, flags);
-        addLayer_l(layer);
-    } else {
-        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
-        layer.clear();
-    }
-    return layer;
-}
-
-sp<LayerBaseClient> SurfaceFlinger::createBlurSurfaceLocked(
-        const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
-{
-    sp<LayerBlur> layer = new LayerBlur(this, display, client, id);
-    layer->initStates(w, h, flags);
-    addLayer_l(layer);
-    return layer;
-}
-
-sp<LayerBaseClient> SurfaceFlinger::createDimSurfaceLocked(
-        const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
-{
-    sp<LayerDim> layer = new LayerDim(this, display, client, id);
-    layer->initStates(w, h, flags);
-    addLayer_l(layer);
-    return layer;
-}
-
-sp<LayerBaseClient> SurfaceFlinger::createPushBuffersSurfaceLocked(
-        const sp<Client>& client, DisplayID display,
-        int32_t id, uint32_t w, uint32_t h, uint32_t flags)
-{
-    sp<LayerBuffer> layer = new LayerBuffer(this, display, client, id);
-    layer->initStates(w, h, flags);
-    addLayer_l(layer);
-    return layer;
-}
-
-status_t SurfaceFlinger::removeSurface(SurfaceID index)
-{
-    /*
-     * called by the window manager, when a surface should be marked for
-     * destruction.
-     * 
-     * The surface is removed from the current and drawing lists, but placed
-     * in the purgatory queue, so it's not destroyed right-away (we need
-     * to wait for all client's references to go away first).
-     */
-
-    status_t err = NAME_NOT_FOUND;
-    Mutex::Autolock _l(mStateLock);
-    sp<LayerBaseClient> layer = getLayerUser_l(index);
-    if (layer != 0) {
-        err = purgatorizeLayer_l(layer);
-        if (err == NO_ERROR) {
-            setTransactionFlags(eTransactionNeeded);
-        }
-    }
-    return err;
-}
-
-status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
-{
-    // called by ~ISurface() when all references are gone
-    
-    class MessageDestroySurface : public MessageBase {
-        SurfaceFlinger* flinger;
-        sp<LayerBaseClient> layer;
-    public:
-        MessageDestroySurface(
-                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
-            : flinger(flinger), layer(layer) { }
-        virtual bool handler() {
-            sp<LayerBaseClient> l(layer);
-            layer.clear(); // clear it outside of the lock;
-            Mutex::Autolock _l(flinger->mStateLock);
-            /*
-             * remove the layer from the current list -- chances are that it's 
-             * not in the list anyway, because it should have been removed 
-             * already upon request of the client (eg: window manager). 
-             * However, a buggy client could have not done that.
-             * Since we know we don't have any more clients, we don't need
-             * to use the purgatory.
-             */
-            status_t err = flinger->removeLayer_l(l);
-            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
-                    "error removing layer=%p (%s)", l.get(), strerror(-err));
-            return true;
-        }
-    };
-
-    mEventQueue.postMessage( new MessageDestroySurface(this, layer) );
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::setClientState(
-        ClientID cid,
-        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));
-        if (layer != 0) {
-            const uint32_t what = s.what;
-            if (what & ePositionChanged) {
-                if (layer->setPosition(s.x, s.y))
-                    flags |= eTraversalNeeded;
-            }
-            if (what & eLayerChanged) {
-                if (layer->setLayer(s.z)) {
-                    mCurrentState.layersSortedByZ.reorder(
-                            layer, &Layer::compareCurrentStateZ);
-                    // we need traversal (state changed)
-                    // AND transaction (list changed)
-                    flags |= eTransactionNeeded|eTraversalNeeded;
-                }
-            }
-            if (what & eSizeChanged) {
-                if (layer->setSize(s.w, s.h)) {
-                    flags |= eTraversalNeeded;
-                    mResizeTransationPending = true;
-                }
-            }
-            if (what & eAlphaChanged) {
-                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
-                    flags |= eTraversalNeeded;
-            }
-            if (what & eMatrixChanged) {
-                if (layer->setMatrix(s.matrix))
-                    flags |= eTraversalNeeded;
-            }
-            if (what & eTransparentRegionChanged) {
-                if (layer->setTransparentRegionHint(s.transparentRegion))
-                    flags |= eTraversalNeeded;
-            }
-            if (what & eVisibilityChanged) {
-                if (layer->setFlags(s.flags, s.mask))
-                    flags |= eTraversalNeeded;
-            }
-        }
-    }
-    if (flags) {
-        setTransactionFlags(flags);
-    }
-    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
-    android_atomic_or(eConsoleReleased, &mConsoleSignals);
-    signalEvent();
-}
-
-void SurfaceFlinger::screenAcquired(int dpy)
-{
-    // this may be called by a signal handler, we can't do too much in here
-    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
-    signalEvent();
-}
-
-status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 1024;
-    char buffer[SIZE];
-    String8 result;
-    if (!mDump.checkCalling()) {
-        snprintf(buffer, SIZE, "Permission Denial: "
-                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
-                IPCThreadState::self()->getCallingPid(),
-                IPCThreadState::self()->getCallingUid());
-        result.append(buffer);
-    } else {
-
-        // figure out if we're stuck somewhere
-        const nsecs_t now = systemTime();
-        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
-        const nsecs_t inTransaction(mDebugInTransaction);
-        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
-        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
-
-        // Try to get the main lock, but don't insist if we can't
-        // (this would indicate SF is stuck, but we want to be able to
-        // print something in dumpsys).
-        int retry = 3;
-        while (mStateLock.tryLock()<0 && --retry>=0) {
-            usleep(1000000);
-        }
-        const bool locked(retry >= 0);
-        if (!locked) {
-            snprintf(buffer, SIZE, 
-                    "SurfaceFlinger appears to be unresponsive, "
-                    "dumping anyways (no locks held)\n");
-            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;
-            }
-            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,
-                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
-                mFreezeDisplay?"yes":"no", mFreezeCount,
-                mCurrentState.orientation, hw.canDraw());
-        result.append(buffer);
-        snprintf(buffer, SIZE,
-                "  last eglSwapBuffers() time: %f us\n"
-                "  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);
-
-        if (locked) {
-            mStateLock.unlock();
-        }
-    }
-    write(fd, result.string(), result.size());
-    return NO_ERROR;
-}
-
-status_t SurfaceFlinger::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    switch (code) {
-        case CREATE_CONNECTION:
-        case OPEN_GLOBAL_TRANSACTION:
-        case CLOSE_GLOBAL_TRANSACTION:
-        case SET_ORIENTATION:
-        case FREEZE_DISPLAY:
-        case UNFREEZE_DISPLAY:
-        case BOOT_FINISHED:
-        {
-            // codes that require permission check
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int uid = ipc->getCallingUid();
-            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
-                LOGE("Permission Denial: "
-                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-                return PERMISSION_DENIED;
-            }
-        }
-    }
-    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
-    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
-        CHECK_INTERFACE(ISurfaceComposer, data, reply);
-        if (UNLIKELY(!mHardwareTest.checkCalling())) {
-            IPCThreadState* ipc = IPCThreadState::self();
-            const int pid = ipc->getCallingPid();
-            const int uid = ipc->getCallingUid();
-            LOGE("Permission Denial: "
-                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
-            return PERMISSION_DENIED;
-        }
-        int n;
-        switch (code) {
-            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
-                return NO_ERROR;
-            case 1001:  // SHOW_FPS, NOT SUPPORTED ANYMORE
-                return NO_ERROR;
-            case 1002:  // SHOW_UPDATES
-                n = data.readInt32();
-                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
-                return NO_ERROR;
-            case 1003:  // SHOW_BACKGROUND
-                n = data.readInt32();
-                mDebugBackground = n ? 1 : 0;
-                return NO_ERROR;
-            case 1004:{ // repaint everything
-                Mutex::Autolock _l(mStateLock);
-                const DisplayHardware& hw(graphicPlane(0).displayHardware());
-                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
-                signalEvent();
-                return NO_ERROR;
-            }
-            case 1005:{ // force transaction
-                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
-                return NO_ERROR;
-            }
-            case 1007: // set mFreezeCount
-                mFreezeCount = data.readInt32();
-                mFreezeDisplayTime = 0;
-                return NO_ERROR;
-            case 1010:  // interrogate.
-                reply->writeInt32(0);
-                reply->writeInt32(0);
-                reply->writeInt32(mDebugRegion);
-                reply->writeInt32(mDebugBackground);
-                return NO_ERROR;
-            case 1013: {
-                Mutex::Autolock _l(mStateLock);
-                const DisplayHardware& hw(graphicPlane(0).displayHardware());
-                reply->writeInt32(hw.getPageFlipCount());
-            }
-            return NO_ERROR;
-        }
-    }
-    return err;
-}
-
-// ---------------------------------------------------------------------------
-#if 0
-#pragma mark -
-#endif
-
-Client::Client(ClientID clientID, const sp<SurfaceFlinger>& flinger)
-    : ctrlblk(0), cid(clientID), mPid(0), mBitmap(0), mFlinger(flinger)
-{
-    const int pgsize = getpagesize();
-    const int cblksize = ((sizeof(SharedClient)+(pgsize-1))&~(pgsize-1));
-
-    mCblkHeap = new MemoryHeapBase(cblksize, 0,
-            "SurfaceFlinger Client control-block");
-
-    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
-    if (ctrlblk) { // construct the shared structure in-place.
-        new(ctrlblk) SharedClient;
-    }
-}
-
-Client::~Client() {
-    if (ctrlblk) {
-        ctrlblk->~SharedClient();  // destroy our shared-structure.
-    }
-}
-
-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 Client::bindLayer(const sp<LayerBaseClient>& layer, int32_t id)
-{
-    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);
-    }
-}
-
-bool Client::isValid(int32_t i) const {
-    return (uint32_t(i)<NUM_LAYERS_MAX) && (mBitmap & (1<<(31-i)));
-}
-
-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)
-{
-}
-
-// ---------------------------------------------------------------------------
-#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,
-        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);
-}
-
-status_t BClient::destroySurface(SurfaceID sid)
-{
-    sid |= (mId << 16); // add the client-part to id
-    return mFlinger->removeSurface(sid);
-}
-
-status_t BClient::setState(int32_t count, const layer_state_t* states)
-{
-    return mFlinger->setClientState(mId, count, states);
-}
-
-// ---------------------------------------------------------------------------
-
-GraphicPlane::GraphicPlane()
-    : mHw(0)
-{
-}
-
-GraphicPlane::~GraphicPlane() {
-    delete mHw;
-}
-
-bool GraphicPlane::initialized() const {
-    return mHw ? true : false;
-}
-
-int GraphicPlane::getWidth() const {
-    return mWidth;
-}
-
-int GraphicPlane::getHeight() const {
-    return mHeight;
-}
-
-void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
-{
-    mHw = hw;
-
-    // initialize the display orientation transform.
-    // it's a constant that should come from the display driver.
-    int displayOrientation = ISurfaceComposer::eOrientationDefault;
-    char property[PROPERTY_VALUE_MAX];
-    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
-        //displayOrientation
-        switch (atoi(property)) {
-        case 90:
-            displayOrientation = ISurfaceComposer::eOrientation90;
-            break;
-        case 270:
-            displayOrientation = ISurfaceComposer::eOrientation270;
-            break;
-        }
-    }
-
-    const float w = hw->getWidth();
-    const float h = hw->getHeight();
-    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
-            &mDisplayTransform);
-    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
-        mDisplayWidth = h;
-        mDisplayHeight = w;
-    } else {
-        mDisplayWidth = w;
-        mDisplayHeight = h;
-    }
-
-    setOrientation(ISurfaceComposer::eOrientationDefault);
-}
-
-status_t GraphicPlane::orientationToTransfrom(
-        int orientation, int w, int h, Transform* tr)
-{
-    uint32_t flags = 0;
-    switch (orientation) {
-    case ISurfaceComposer::eOrientationDefault:
-        flags = Transform::ROT_0;
-        break;
-    case ISurfaceComposer::eOrientation90:
-        flags = Transform::ROT_90;
-        break;
-    case ISurfaceComposer::eOrientation180:
-        flags = Transform::ROT_180;
-        break;
-    case ISurfaceComposer::eOrientation270:
-        flags = Transform::ROT_270;
-        break;
-    default:
-        return BAD_VALUE;
-    }
-    tr->set(flags, w, h);
-    return NO_ERROR;
-}
-
-status_t GraphicPlane::setOrientation(int orientation)
-{
-    // If the rotation can be handled in hardware, this is where
-    // the magic should happen.
-
-    const DisplayHardware& hw(displayHardware());
-    const float w = mDisplayWidth;
-    const float h = mDisplayHeight;
-    mWidth = int(w);
-    mHeight = int(h);
-
-    Transform orientationTransform;
-    GraphicPlane::orientationToTransfrom(orientation, w, h,
-            &orientationTransform);
-    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
-        mWidth = int(h);
-        mHeight = int(w);
-    }
-
-    mOrientation = orientation;
-    mGlobalTransform = mDisplayTransform * orientationTransform;
-    return NO_ERROR;
-}
-
-const DisplayHardware& GraphicPlane::displayHardware() const {
-    return *mHw;
-}
-
-const Transform& GraphicPlane::transform() const {
-    return mGlobalTransform;
-}
-
-EGLDisplay GraphicPlane::getEGLDisplay() const {
-    return mHw->getEGLDisplay();
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
deleted file mode 100644
index d75dc15..0000000
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ /dev/null
@@ -1,420 +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_SURFACE_FLINGER_H
-#define ANDROID_SURFACE_FLINGER_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
-#include <utils/threads.h>
-#include <utils/Atomic.h>
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include <binder/IMemory.h>
-#include <binder/Permission.h>
-
-#include <ui/PixelFormat.h>
-#include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.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 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
-{
-public:
-            Client(ClientID cid, 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);
-
-    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;
-
-    
-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;
-};
-
-// ---------------------------------------------------------------------------
-
-class GraphicPlane
-{
-public:
-    static status_t orientationToTransfrom(int orientation, int w, int h,
-            Transform* tr);
-
-                                GraphicPlane();
-                                ~GraphicPlane();
-
-        bool                    initialized() const;
-
-        void                    setDisplayHardware(DisplayHardware *);
-        status_t                setOrientation(int orientation);
-        int                     getOrientation() const { return mOrientation; }
-        int                     getWidth() const;
-        int                     getHeight() const;
-
-        const DisplayHardware&  displayHardware() const;
-        const Transform&        transform() const;
-        EGLDisplay              getEGLDisplay() const;
-        
-private:
-                                GraphicPlane(const GraphicPlane&);
-        GraphicPlane            operator = (const GraphicPlane&);
-
-        DisplayHardware*        mHw;
-        Transform               mGlobalTransform;
-        Transform               mDisplayTransform;
-        int                     mOrientation;
-        float                   mDisplayWidth;
-        float                   mDisplayHeight;
-        int                     mWidth;
-        int                     mHeight;
-};
-
-// ---------------------------------------------------------------------------
-
-enum {
-    eTransactionNeeded      = 0x01,
-    eTraversalNeeded        = 0x02
-};
-
-class SurfaceFlinger : public BnSurfaceComposer, protected Thread
-{
-public:
-    static void instantiate();
-    static void shutdown();
-
-                    SurfaceFlinger();
-    virtual         ~SurfaceFlinger();
-            void    init();
-
-    virtual status_t onTransact(
-        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-
-    virtual status_t dump(int fd, const Vector<String16>& args);
-
-    // ISurfaceComposer interface
-    virtual sp<ISurfaceFlingerClient>   createConnection();
-    virtual sp<IMemoryHeap>             getCblk() const;
-    virtual void                        bootFinished();
-    virtual void                        openGlobalTransaction();
-    virtual void                        closeGlobalTransaction();
-    virtual status_t                    freezeDisplay(DisplayID dpy, uint32_t flags);
-    virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
-    virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
-    virtual void                        signal() const;
-
-            void                        screenReleased(DisplayID dpy);
-            void                        screenAcquired(DisplayID dpy);
-
-            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);
-    
-private:
-    friend class BClient;
-    friend class LayerBase;
-    friend class LayerBuffer;
-    friend class LayerBaseClient;
-    friend class LayerBaseClient::Surface;
-    friend class Layer;
-    friend class LayerBlur;
-    friend class LayerDim;
-
-    sp<ISurface> createSurface(ClientID client, int pid, const String8& name,
-            ISurfaceFlingerClient::surface_data_t* params,
-            DisplayID display, uint32_t w, uint32_t h, PixelFormat format,
-            uint32_t flags);
-
-    sp<LayerBaseClient> createNormalSurfaceLocked(
-            const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags,
-            PixelFormat& format);
-
-    sp<LayerBaseClient> createBlurSurfaceLocked(
-            const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
-
-    sp<LayerBaseClient> createDimSurfaceLocked(
-            const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
-
-    sp<LayerBaseClient> createPushBuffersSurfaceLocked(
-            const sp<Client>& client, DisplayID display,
-            int32_t id, uint32_t w, uint32_t h, uint32_t flags);
-
-    status_t removeSurface(SurfaceID surface_id);
-    status_t destroySurface(const sp<LayerBaseClient>& layer);
-    status_t setClientState(ClientID cid, int32_t count, const layer_state_t* states);
-
-
-    class LayerVector {
-    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;
-    };
-
-    struct State {
-        State() {
-            orientation = ISurfaceComposer::eOrientationDefault;
-            freezeDisplay = 0;
-        }
-        LayerVector     layersSortedByZ;
-        uint8_t         orientation;
-        uint8_t         orientationType;
-        uint8_t         freezeDisplay;
-    };
-
-    virtual bool        threadLoop();
-    virtual status_t    readyToRun();
-    virtual void        onFirstRef();
-
-public:     // hack to work around gcc 4.0.3 bug
-    const GraphicPlane&     graphicPlane(int dpy) const;
-          GraphicPlane&     graphicPlane(int dpy);
-private:
-
-            void        waitForEvent();
-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(
-                            uint32_t transactionFlags, 
-                            Vector< sp<LayerBase> >& ditchedLayers);
-
-            void        computeVisibleRegions(
-                            LayerVector& currentLayers,
-                            Region& dirtyRegion,
-                            Region& wormholeRegion);
-
-            void        handlePageFlip();
-            bool        lockPageFlip(const LayerVector& currentLayers);
-            void        unlockPageFlip(const LayerVector& currentLayers);
-            void        handleRepaint();
-            void        postFramebuffer();
-            void        composeSurfaces(const Region& dirty);
-            void        unlockClients();
-
-
-            void        destroyConnection(ClientID cid);
-            sp<LayerBaseClient> getLayerUser_l(SurfaceID index) const;
-            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);
-            void        commitTransaction();
-
-
-            friend class FreezeLock;
-            sp<FreezeLock> getFreezeLock() const;
-            inline void incFreezeCount() {
-                if (mFreezeCount == 0)
-                    mFreezeDisplayTime = 0;
-                mFreezeCount++;
-            }
-            inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
-            inline bool hasFreezeRequest() const { return mFreezeDisplay; }
-            inline bool isFrozen() const { 
-                return (mFreezeDisplay || mFreezeCount>0) && mBootFinished;
-            }
-
-            
-            void        debugFlashRegions();
-            void        debugShowFPS() const;
-            void        drawWormhole() const;
-           
-
-    mutable     MessageQueue    mEventQueue;
-    
-                
-                
-                // access must be protected by mStateLock
-    mutable     Mutex                   mStateLock;
-                State                   mCurrentState;
-                State                   mDrawingState;
-    volatile    int32_t                 mTransactionFlags;
-    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;
-
-                // constant members (no synchronization needed for access)
-                sp<IMemoryHeap>             mServerHeap;
-                surface_flinger_cblk_t*     mServerCblk;
-                GLuint                      mWormholeTexName;
-                nsecs_t                     mBootTime;
-                Permission                  mHardwareTest;
-                Permission                  mAccessSurfaceFlinger;
-                Permission                  mDump;
-                
-                // Can only accessed from the main thread, these members
-                // don't need synchronization
-                Region                      mDirtyRegion;
-                Region                      mDirtyRegionRemovedLayer;
-                Region                      mInvalidRegion;
-                Region                      mWormholeRegion;
-                bool                        mVisibleRegionsDirty;
-                bool                        mDeferReleaseConsole;
-                bool                        mFreezeDisplay;
-                int32_t                     mFreezeCount;
-                nsecs_t                     mFreezeDisplayTime;
-
-                // don't use a lock for these, we don't care
-                int                         mDebugRegion;
-                int                         mDebugBackground;
-                volatile nsecs_t            mDebugInSwapBuffers;
-                nsecs_t                     mLastSwapBufferTime;
-                volatile nsecs_t            mDebugInTransaction;
-                nsecs_t                     mLastTransactionTime;
-                bool                        mBootFinished;
-
-                // these are thread safe
-    mutable     Barrier                     mReadyToRunBarrier;
-
-                // atomic variables
-                enum {
-                    eConsoleReleased = 1,
-                    eConsoleAcquired = 2
-                };
-   volatile     int32_t                     mConsoleSignals;
-
-   // only written in the main thread, only read in other threads
-   volatile     int32_t                     mSecureFrameBuffer;
-};
-
-// ---------------------------------------------------------------------------
-
-class FreezeLock : public LightRefBase<FreezeLock> {
-    SurfaceFlinger* mFlinger;
-public:
-    FreezeLock(SurfaceFlinger* flinger)
-        : mFlinger(flinger) {
-        mFlinger->incFreezeCount();
-    }
-    ~FreezeLock() {
-        mFlinger->decFreezeCount();
-    }
-};
-
-// ---------------------------------------------------------------------------
-
-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/libs/surfaceflinger/Tokenizer.cpp b/libs/surfaceflinger/Tokenizer.cpp
deleted file mode 100644
index be3a239..0000000
--- a/libs/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/libs/surfaceflinger/Tokenizer.h b/libs/surfaceflinger/Tokenizer.h
deleted file mode 100644
index 6b3057d..0000000
--- a/libs/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/libs/surfaceflinger/Transform.cpp b/libs/surfaceflinger/Transform.cpp
deleted file mode 100644
index 175f989..0000000
--- a/libs/surfaceflinger/Transform.cpp
+++ /dev/null
@@ -1,392 +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 <math.h>
-
-#include <cutils/compiler.h>
-#include <utils/String8.h>
-#include <ui/Region.h>
-
-#include "Transform.h"
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-// ---------------------------------------------------------------------------
-
-template <typename T> inline T min(T a, T b) {
-    return a<b ? a : b;
-}
-template <typename T> inline T min(T a, T b, T c) {
-    return min(a, min(b, c));
-}
-template <typename T> inline T min(T a, T b, T c, T d) {
-    return min(a, b, min(c, d));
-}
-
-template <typename T> inline T max(T a, T b) {
-    return a>b ? a : b;
-}
-template <typename T> inline T max(T a, T b, T c) {
-    return max(a, max(b, c));
-}
-template <typename T> inline T max(T a, T b, T c, T d) {
-    return max(a, b, max(c, d));
-}
-
-// ---------------------------------------------------------------------------
-
-Transform::Transform() {
-    reset();
-}
-
-Transform::Transform(const Transform&  other)
-    : mMatrix(other.mMatrix), mType(other.mType) {
-}
-
-Transform::Transform(uint32_t orientation) {
-    set(orientation, 0, 0);
-}
-
-Transform::~Transform() {
-}
-
-static const float EPSILON = 0.0f;
-
-bool Transform::isZero(float f) {
-    return fabs(f) <= EPSILON;
-}
-
-bool Transform::absIsOne(float f) {
-    return isZero(fabs(f) - 1.0f);
-}
-
-Transform Transform::operator * (const Transform& rhs) const
-{
-    if (CC_LIKELY(mType == IDENTITY))
-        return rhs;
-
-    Transform r(*this);
-    if (rhs.mType == IDENTITY)
-        return r;
-
-    // TODO: we could use mType to optimize the matrix multiply
-    const mat33& A(mMatrix);
-    const mat33& B(rhs.mMatrix);
-          mat33& D(r.mMatrix);
-    for (int i=0 ; i<3 ; i++) {
-        const float v0 = A[0][i];
-        const float v1 = A[1][i];
-        const float v2 = A[2][i];
-        D[0][i] = v0*B[0][0] + v1*B[0][1] + v2*B[0][2];
-        D[1][i] = v0*B[1][0] + v1*B[1][1] + v2*B[1][2];
-        D[2][i] = v0*B[2][0] + v1*B[2][1] + v2*B[2][2];
-    }
-    r.mType |= rhs.mType;
-
-    // TODO: we could recompute this value from r and rhs
-    r.mType &= 0xFF;
-    r.mType |= UNKNOWN_TYPE;
-    return r;
-}
-
-float const* Transform::operator [] (int i) const {
-    return mMatrix[i].v;
-}
-
-bool Transform::transformed() const {
-    return type() > TRANSLATE;
-}
-
-int Transform::tx() const {
-    return floorf(mMatrix[2][0] + 0.5f);
-}
-
-int Transform::ty() const {
-    return floorf(mMatrix[2][1] + 0.5f);
-}
-
-void Transform::reset() {
-    mType = IDENTITY;
-    for(int i=0 ; i<3 ; i++) {
-        vec3& v(mMatrix[i]);
-        for (int j=0 ; j<3 ; j++)
-            v[j] = ((i==j) ? 1.0f : 0.0f);
-    }
-}
-
-void Transform::set(float tx, float ty)
-{
-    mMatrix[2][0] = tx;
-    mMatrix[2][1] = ty;
-    mMatrix[2][2] = 1.0f;
-
-    if (isZero(tx) && isZero(ty)) {
-        mType &= ~TRANSLATE;
-    } else {
-        mType |= TRANSLATE;
-    }
-}
-
-void Transform::set(float a, float b, float c, float d)
-{
-    mat33& M(mMatrix);
-    M[0][0] = a;    M[1][0] = b;
-    M[0][1] = c;    M[1][1] = d;
-    M[0][2] = 0;    M[1][2] = 0;
-    mType = UNKNOWN_TYPE;
-}
-
-status_t Transform::set(uint32_t flags, float w, float h)
-{
-    if (flags & ROT_INVALID) {
-        // that's not allowed!
-        reset();
-        return BAD_VALUE;
-    }
-
-    mType = flags << 8;
-    float sx = (flags & FLIP_H) ? -1 : 1;
-    float sy = (flags & FLIP_V) ? -1 : 1;
-    float a=0, b=0, c=0, d=0, x=0, y=0;
-    int xmask = 0;
-
-    // computation of x,y
-    // x y
-    // 0 0  0
-    // w 0  ROT90
-    // w h  FLIPH|FLIPV
-    // 0 h  FLIPH|FLIPV|ROT90
-
-    if (flags & ROT_90) {
-        mType |= ROTATE;
-        b = -sy;
-        c = sx;
-        xmask = 1;
-    } else {
-        a = sx;
-        d = sy;
-    }
-
-    if (flags & FLIP_H) {
-        mType ^= SCALE;
-        xmask ^= 1;
-    }
-
-    if (flags & FLIP_V) {
-        mType ^= SCALE;
-        y = h;
-    }
-
-    if ((flags & ROT_180) == ROT_180) {
-        mType |= ROTATE;
-    }
-
-    if (xmask) {
-        x = w;
-    }
-
-    if (!isZero(x) || !isZero(y)) {
-        mType |= TRANSLATE;
-    }
-
-    mat33& M(mMatrix);
-    M[0][0] = a;    M[1][0] = b;    M[2][0] = x;
-    M[0][1] = c;    M[1][1] = d;    M[2][1] = y;
-    M[0][2] = 0;    M[1][2] = 0;    M[2][2] = 1;
-
-    return NO_ERROR;
-}
-
-Transform::vec2 Transform::transform(const vec2& v) const {
-    vec2 r;
-    const mat33& M(mMatrix);
-    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0];
-    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1];
-    return r;
-}
-
-Transform::vec3 Transform::transform(const vec3& v) const {
-    vec3 r;
-    const mat33& M(mMatrix);
-    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0]*v[2];
-    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1]*v[2];
-    r[2] = M[0][2]*v[0] + M[1][2]*v[1] + M[2][2]*v[2];
-    return r;
-}
-
-void Transform::transform(fixed1616* 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;
-}
-
-Rect Transform::makeBounds(int w, int h) const
-{
-    return transform( Rect(w, h) );
-}
-
-Rect Transform::transform(const Rect& bounds) const
-{
-    Rect r;
-    vec2 lt( bounds.left,  bounds.top    );
-    vec2 rt( bounds.right, bounds.top    );
-    vec2 lb( bounds.left,  bounds.bottom );
-    vec2 rb( bounds.right, bounds.bottom );
-
-    lt = transform(lt);
-    rt = transform(rt);
-    lb = transform(lb);
-    rb = transform(rb);
-
-    r.left   = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
-    r.top    = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
-    r.right  = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
-    r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
-
-    return r;
-}
-
-Region Transform::transform(const Region& reg) const
-{
-    Region out;
-    if (CC_UNLIKELY(transformed())) {
-        if (CC_LIKELY(preserveRects())) {
-            Region::const_iterator it = reg.begin();
-            Region::const_iterator const end = reg.end();
-            while (it != end) {
-                out.orSelf(transform(*it++));
-            }
-        } else {
-            out.set(transform(reg.bounds()));
-        }
-    } else {
-        out = reg.translate(tx(), ty());
-    }
-    return out;
-}
-
-uint32_t Transform::type() const
-{
-    if (mType & UNKNOWN_TYPE) {
-        // recompute what this transform is
-
-        const mat33& M(mMatrix);
-        const float a = M[0][0];
-        const float b = M[1][0];
-        const float c = M[0][1];
-        const float d = M[1][1];
-        const float x = M[2][0];
-        const float y = M[2][1];
-
-        bool scale = false;
-        uint32_t flags = ROT_0;
-        if (isZero(b) && isZero(c)) {
-            if (a<0)    flags |= FLIP_H;
-            if (d<0)    flags |= FLIP_V;
-            if (!absIsOne(a) || !absIsOne(d)) {
-                scale = true;
-            }
-        } else if (isZero(a) && isZero(d)) {
-            flags |= ROT_90;
-            if (b>0)    flags |= FLIP_H;
-            if (c<0)    flags |= FLIP_V;
-            if (!absIsOne(b) || !absIsOne(c)) {
-                scale = true;
-            }
-        } else {
-            flags = ROT_INVALID;
-        }
-
-        mType = flags << 8;
-        if (flags & ROT_INVALID) {
-            mType |= UNKNOWN;
-        } else {
-            if ((flags & ROT_90) || ((flags & ROT_180) == ROT_180))
-                mType |= ROTATE;
-            if (flags & FLIP_H)
-                mType ^= SCALE;
-            if (flags & FLIP_V)
-                mType ^= SCALE;
-            if (scale)
-                mType |= SCALE;
-        }
-
-        if (!isZero(x) || !isZero(y))
-            mType |= TRANSLATE;
-    }
-    return mType;
-}
-
-uint32_t Transform::getType() const {
-    return type() & 0xFF;
-}
-
-uint32_t Transform::getOrientation() const
-{
-    return (type() >> 8) & 0xFF;
-}
-
-bool Transform::preserveRects() const
-{
-    return (type() & ROT_INVALID) ? false : true;
-}
-
-void Transform::dump(const char* name) const
-{
-    type(); // updates the type
-
-    String8 flags, type;
-    const mat33& m(mMatrix);
-    uint32_t orient = mType >> 8;
-
-    if (orient&ROT_INVALID) {
-        flags.append("ROT_INVALID ");
-    } else {
-        if (orient&ROT_90) {
-            flags.append("ROT_90 ");
-        } else {
-            flags.append("ROT_0 ");
-        }
-        if (orient&FLIP_V)
-            flags.append("FLIP_V ");
-        if (orient&FLIP_H)
-            flags.append("FLIP_H ");
-    }
-
-    if (!(mType&(SCALE|ROTATE|TRANSLATE)))
-        type.append("IDENTITY ");
-    if (mType&SCALE)
-        type.append("SCALE ");
-    if (mType&ROTATE)
-        type.append("ROTATE ");
-    if (mType&TRANSLATE)
-        type.append("TRANSLATE ");
-
-    LOGD("%s 0x%08x (%s, %s)", name, mType, flags.string(), type.string());
-    LOGD("%.4f  %.4f  %.4f", m[0][0], m[1][0], m[2][0]);
-    LOGD("%.4f  %.4f  %.4f", m[0][1], m[1][1], m[2][1]);
-    LOGD("%.4f  %.4f  %.4f", m[0][2], m[1][2], m[2][2]);
-}
-
-// ---------------------------------------------------------------------------
-
-}; // namespace android
diff --git a/libs/surfaceflinger/Transform.h b/libs/surfaceflinger/Transform.h
deleted file mode 100644
index 2e5b893..0000000
--- a/libs/surfaceflinger/Transform.h
+++ /dev/null
@@ -1,128 +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_TRANSFORM_H
-#define ANDROID_TRANSFORM_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-namespace android {
-
-class Region;
-
-// ---------------------------------------------------------------------------
-
-class Transform
-{
-public:
-                    Transform();
-                    Transform(const Transform&  other);
-           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,
-                FLIP_H  = 0x00000001,
-                FLIP_V  = 0x00000002,
-                ROT_90  = 0x00000004,
-                ROT_180 = FLIP_H|FLIP_V,
-                ROT_270 = ROT_180|ROT_90,
-                ROT_INVALID = 0x80
-            };
-
-            enum type_mask {
-                IDENTITY            = 0,
-                TRANSLATE           = 0x1,
-                ROTATE              = 0x2,
-                SCALE               = 0x4,
-                UNKNOWN             = 0x8
-            };
-
-            // query the transform
-            bool        transformed() const;
-            bool        preserveRects() const;
-            uint32_t    getType() const;
-            uint32_t    getOrientation() const;
-
-            float const* operator [] (int i) const;  // returns column i
-            int     tx() const;
-            int     ty() const;
-
-            // modify the transform
-            void        reset();
-            void        set(float tx, float ty);
-            void        set(float a, float b, float c, float d);
-            status_t    set(uint32_t flags, float w, float h);
-
-            // transform data
-            Rect    makeBounds(int w, int h) const;
-            void    transform(fixed1616* point, int x, int y) const;
-            Region  transform(const Region& reg) const;
-            Transform operator * (const Transform& rhs) const;
-
-            // for debugging
-            void dump(const char* name) const;
-
-private:
-    struct vec3 {
-        float v[3];
-        inline vec3() { }
-        inline vec3(float a, float b, float c) {
-            v[0] = a; v[1] = b; v[2] = c;
-        }
-        inline float operator [] (int i) const { return v[i]; }
-        inline float& operator [] (int i) { return v[i]; }
-    };
-    struct vec2 {
-        float v[2];
-        inline vec2() { }
-        inline vec2(float a, float b) {
-            v[0] = a; v[1] = b;
-        }
-        inline float operator [] (int i) const { return v[i]; }
-        inline float& operator [] (int i) { return v[i]; }
-    };
-    struct mat33 {
-        vec3 v[3];
-        inline const vec3& operator [] (int i) const { return v[i]; }
-        inline vec3& operator [] (int i) { return v[i]; }
-    };
-
-    enum { UNKNOWN_TYPE = 0x80000000 };
-
-    // assumes the last row is < 0 , 0 , 1 >
-    vec2 transform(const vec2& v) const;
-    vec3 transform(const vec3& v) const;
-    Rect transform(const Rect& bounds) const;
-    uint32_t type() const;
-    static bool absIsOne(float f);
-    static bool isZero(float f);
-
-    mat33               mMatrix;
-    mutable uint32_t    mType;
-};
-
-// ---------------------------------------------------------------------------
-}; // namespace android
-
-#endif /* ANDROID_TRANSFORM_H */
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..969ee79 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
@@ -115,6 +124,42 @@
         remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
     }
 
+    virtual status_t captureScreen(DisplayID dpy,
+            sp<IMemoryHeap>* heap,
+            uint32_t* width, uint32_t* height, PixelFormat* format,
+            uint32_t reqWidth, uint32_t reqHeight)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(dpy);
+        data.writeInt32(reqWidth);
+        data.writeInt32(reqHeight);
+        remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
+        *heap = interface_cast<IMemoryHeap>(reply.readStrongBinder());
+        *width = reply.readInt32();
+        *height = reply.readInt32();
+        *format = reply.readInt32();
+        return reply.readInt32();
+    }
+
+    virtual status_t turnElectronBeamOff(int32_t mode)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(mode);
+        remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_OFF, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t turnElectronBeamOn(int32_t mode)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        data.writeInt32(mode);
+        remote()->transact(BnSurfaceComposer::TURN_ELECTRON_BEAM_ON, data, &reply);
+        return reply.readInt32();
+    }
+
     virtual void signal() const
     {
         Parcel data, reply;
@@ -136,6 +181,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();
@@ -176,6 +226,34 @@
             sp<IBinder> b = getCblk()->asBinder();
             reply->writeStrongBinder(b);
         } break;
+        case CAPTURE_SCREEN: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            DisplayID dpy = data.readInt32();
+            uint32_t reqWidth = data.readInt32();
+            uint32_t reqHeight = data.readInt32();
+            sp<IMemoryHeap> heap;
+            uint32_t w, h;
+            PixelFormat f;
+            status_t res = captureScreen(dpy, &heap, &w, &h, &f,
+                    reqWidth, reqHeight);
+            reply->writeStrongBinder(heap->asBinder());
+            reply->writeInt32(w);
+            reply->writeInt32(h);
+            reply->writeInt32(f);
+            reply->writeInt32(res);
+        } break;
+        case TURN_ELECTRON_BEAM_OFF: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            int32_t mode = data.readInt32();
+            status_t res = turnElectronBeamOff(mode);
+            reply->writeInt32(res);
+        }
+        case TURN_ELECTRON_BEAM_ON: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            int32_t mode = data.readInt32();
+            status_t res = turnElectronBeamOn(mode);
+            reply->writeInt32(res);
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
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..4bc5d9e 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,10 +275,22 @@
     return NO_ERROR;
 }
 
-SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb)
-    : UpdateBase(sbb) {    
+SharedBufferClient::DequeueUpdate::DequeueUpdate(SharedBufferBase* sbb)
+    : UpdateBase(sbb) {
 }
-ssize_t SharedBufferClient::UndoDequeueUpdate::operator()() {
+ssize_t SharedBufferClient::DequeueUpdate::operator()() {
+    if (android_atomic_dec(&stack.available) == 0) {
+        LOGW("dequeue probably called from multiple threads!");
+    }
+    return NO_ERROR;
+}
+
+SharedBufferClient::CancelUpdate::CancelUpdate(SharedBufferBase* sbb,
+        int tail, int buf)
+    : UpdateBase(sbb), tail(tail), buf(buf) {
+}
+ssize_t SharedBufferClient::CancelUpdate::operator()() {
+    stack.index[tail] = buf;
     android_atomic_inc(&stack.available);
     return NO_ERROR;
 }
@@ -193,8 +301,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 +316,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.headBuf, &stack.inUse);
 
     // Decrement the number of queued buffers 
     int32_t queued;
@@ -221,16 +332,17 @@
         }
     } 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;
+    const int8_t headBuf = stack.index[head];
+    stack.headBuf = headBuf;
+    android_atomic_write(headBuf, &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 +362,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)
 {
+    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 +396,12 @@
     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;
+    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 +411,28 @@
 
 status_t SharedBufferClient::undoDequeue(int buf)
 {
-    UndoDequeueUpdate update(this);
+    return cancel(buf);
+}
+
+status_t SharedBufferClient::cancel(int buf)
+{
+    RWLock::AutoRLock _rd(mLock);
+
+    // calculate the new position of the tail index (essentially tail--)
+    int localTail = (tail + mNumBuffers - 1) % mNumBuffers;
+    CancelUpdate update(this, localTail, buf);
     status_t err = updateCondition( update );
     if (err == NO_ERROR) {
-        tail = computeTail();
+        tail = localTail;
     }
     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 +440,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 +557,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 +585,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 +661,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..854a3c6 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,14 +26,13 @@
 #include <utils/CallStack.h>
 #include <utils/Log.h>
 
-#include <pixelflinger/pixelflinger.h>
-
 #include <binder/IPCThreadState.h>
 #include <binder/IMemory.h>
 
 #include <ui/DisplayInfo.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicBufferMapper.h>
+#include <ui/GraphicLog.h>
 #include <ui/Rect.h>
 
 #include <surfaceflinger/Surface.h>
@@ -55,6 +52,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 +66,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 +105,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 +152,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 +231,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 +273,181 @@
 //  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::cancelBuffer     = cancelBuffer;
+    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 +455,94 @@
 
     // 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::cancelBuffer(ANativeWindow* window,
+        android_native_buffer_t* buffer) {
+    Surface* self = getSelf(window);
+    return self->cancelBuffer(buffer);
+}
+
+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,49 +554,62 @@
 
 // ----------------------------------------------------------------------------
 
-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;
 
+    GraphicLog& logger(GraphicLog::getInstance());
+    logger.log(GraphicLog::SF_APP_DEQUEUE_BEFORE, mIdentity, -1);
+
     ssize_t bufIdx = mSharedBufferClient->dequeue();
+
+    logger.log(GraphicLog::SF_APP_DEQUEUE_AFTER, mIdentity, bufIdx);
+
     if (bufIdx < 0) {
         LOGE("error dequeuing a buffer (%s)", strerror(bufIdx));
         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;
     }
@@ -524,22 +624,54 @@
     return err;
 }
 
+int Surface::cancelBuffer(android_native_buffer_t* buffer)
+{
+    status_t err = validate();
+    switch (err) {
+    case NO_ERROR:
+        // no error, common case
+        break;
+    case INVALID_OPERATION:
+        // legitimate errors here
+        return err;
+    default:
+        // other errors happen because the surface is now invalid,
+        // for instance because it has been destroyed. In this case,
+        // we just fail silently (canceling a buffer is not technically
+        // an error at this point)
+        return NO_ERROR;
+    }
+
+    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
+
+    err = mSharedBufferClient->cancel(bufIdx);
+
+    LOGE_IF(err, "error canceling buffer %d (%s)", bufIdx, strerror(-err));
+    return err;
+}
+
+
 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));
+
+    GraphicLog& logger(GraphicLog::getInstance());
+    logger.log(GraphicLog::SF_APP_LOCK_BEFORE, mIdentity, bufIdx);
+
     err = mSharedBufferClient->lock(bufIdx);
+
+    logger.log(GraphicLog::SF_APP_LOCK_AFTER, mIdentity, bufIdx);
+
     LOGE_IF(err, "error locking buffer %d (%s)", bufIdx, strerror(-err));
     return err;
 }
 
 int Surface::queueBuffer(android_native_buffer_t* buffer)
-{   
-    sp<SurfaceComposerClient> client(getClient());
+{
     status_t err = validate();
     if (err != NO_ERROR)
         return err;
@@ -548,14 +680,19 @@
         mDirtyRegion.set(mSwapRectangle);
     }
     
-    int32_t bufIdx = GraphicBuffer::getSelf(buffer)->getIndex();
+    int32_t bufIdx = getBufferIndex(GraphicBuffer::getSelf(buffer));
+
+    GraphicLog::getInstance().log(GraphicLog::SF_APP_QUEUE, mIdentity, bufIdx);
+
+    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 +715,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 +730,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 +761,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 +825,77 @@
     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);
+    if (mConnected == NATIVE_WINDOW_API_EGL) {
+        return INVALID_OPERATION;
+    }
+
+    mBufferInfo.set(w, h, format);
+    if (format != 0) {
+        // we update the format of the surface as reported by query().
+        // this is to allow applications to change the format of a surface's
+        // buffer, and have it reflected in EGL; which is needed for
+        // EGLConfig validation.
+        mFormat = 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 +906,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 +932,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 +1008,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 +1020,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 +1034,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 +1058,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 3117495..f270461 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>, sp<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);
-    }
-
-    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));
-        if (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,70 @@
     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;
 }
 
+// ----------------------------------------------------------------------------
+
+ScreenshotClient::ScreenshotClient()
+    : mWidth(0), mHeight(0), mFormat(PIXEL_FORMAT_NONE) {
+}
+
+status_t ScreenshotClient::update() {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == NULL) return NO_INIT;
+    mHeap = 0;
+    return s->captureScreen(0, &mHeap,
+            &mWidth, &mHeight, &mFormat, 0, 0);
+}
+
+status_t ScreenshotClient::update(uint32_t reqWidth, uint32_t reqHeight) {
+    sp<ISurfaceComposer> s(ComposerService::getComposerService());
+    if (s == NULL) return NO_INIT;
+    mHeap = 0;
+    return s->captureScreen(0, &mHeap,
+            &mWidth, &mHeight, &mFormat, reqWidth, reqHeight);
+}
+
+void ScreenshotClient::release() {
+    mHeap = 0;
+}
+
+void const* ScreenshotClient::getPixels() const {
+    return mHeap->getBase();
+}
+
+uint32_t ScreenshotClient::getWidth() const {
+    return mWidth;
+}
+
+uint32_t ScreenshotClient::getHeight() const {
+    return mHeight;
+}
+
+PixelFormat ScreenshotClient::getFormat() const {
+    return mFormat;
+}
+
+uint32_t ScreenshotClient::getStride() const {
+    return mWidth;
+}
+
+size_t ScreenshotClient::getSize() const {
+    return mHeap->getSize();
+}
+
+// ----------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/libs/surfaceflinger/tests/Android.mk b/libs/surfaceflinger_client/tests/Android.mk
similarity index 100%
rename from libs/surfaceflinger/tests/Android.mk
rename to libs/surfaceflinger_client/tests/Android.mk
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..c4a09d6 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -9,8 +9,14 @@
 	GraphicBuffer.cpp \
 	GraphicBufferAllocator.cpp \
 	GraphicBufferMapper.cpp \
+	GraphicLog.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
+	Input.cpp \
+	InputDispatcher.cpp \
+	InputManager.cpp \
+	InputReader.cpp \
+	InputTransport.cpp \
 	IOverlay.cpp \
 	Overlay.cpp \
 	PixelFormat.cpp \
@@ -33,3 +39,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 d45eaf0..41daa9c 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -54,10 +54,12 @@
  */
 #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
-#define id_to_index(id)         ((id&ID_MASK)+1)
 
 #ifndef ABS_MT_TOUCH_MAJOR
 #define ABS_MT_TOUCH_MAJOR      0x30    /* Major axis of touching ellipse */
@@ -71,6 +73,10 @@
 #define ABS_MT_POSITION_Y       0x36    /* Center Y ellipse position */
 #endif
 
+#define INDENT "  "
+#define INDENT2 "    "
+#define INDENT3 "      "
+
 namespace android {
 
 static const char *WAKE_LOCK_ID = "KeyEvents";
@@ -82,9 +88,13 @@
     return (v1 > v2) ? v1 : v2;
 }
 
+static inline const char* toString(bool value) {
+    return value ? "true" : "false";
+}
+
 EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name)
     : id(_id), path(_path), name(name), classes(0)
-    , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), next(NULL) {
+    , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), fd(-1), next(NULL) {
 }
 
 EventHub::device_t::~device_t() {
@@ -96,7 +106,8 @@
     : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0)
     , mDevicesById(0), mNumDevicesById(0)
     , mOpeningDevices(0), mClosingDevices(0)
-    , mDevices(0), mFDs(0), mFDCount(0), mOpened(false)
+    , mDevices(0), mFDs(0), mFDCount(0), mOpened(false), mNeedToSendFinishedDeviceScan(false)
+    , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0)
 {
     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
 #ifdef EV_SW
@@ -121,7 +132,7 @@
 String8 EventHub::getDeviceName(int32_t deviceId) const
 {
     AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
+    device_t* device = getDeviceLocked(deviceId);
     if (device == NULL) return String8();
     return device->name;
 }
@@ -129,106 +140,76 @@
 uint32_t EventHub::getDeviceClasses(int32_t deviceId) const
 {
     AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
+    device_t* device = getDeviceLocked(deviceId);
     if (device == NULL) return 0;
     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);
+    device_t* device = getDeviceLocked(deviceId);
     if (device == NULL) return -1;
 
     struct input_absinfo info;
 
-    if(ioctl(mFDs[id_to_index(device->id)].fd, EVIOCGABS(axis), &info)) {
-        LOGE("Error reading absolute controller %d for device %s fd %d\n",
-             axis, device->name.string(), mFDs[id_to_index(device->id)].fd);
-        return -1;
+    if(ioctl(device->fd, EVIOCGABS(axis), &info)) {
+        LOGW("Error reading absolute controller %d for device %s fd %d\n",
+             axis, device->name.string(), device->fd);
+        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 = getDeviceLocked(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(mFDs[id_to_index(device->id)].fd,
-                   EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
-            return test_bit(sw, sw_bitmask) ? 1 : 0;
-        }
-    }
-#endif
-    
-    return -1;
-}
-
-int EventHub::getScancodeState(int code) const
-{
-    return getScancodeState(mFirstKeyboardId, code);
-}
-
-int EventHub::getScancodeState(int32_t deviceId, int code) 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(mFDs[id_to_index(device->id)].fd,
-                   EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
-            return test_bit(code, key_bitmask) ? 1 : 0;
-        }
-    }
-    
-    return -1;
-}
-
-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;
-    
-    Vector<int32_t> scanCodes;
-    device->layoutMap->findScancodes(code, &scanCodes);
-    
-    uint8_t key_bitmask[(KEY_MAX+7)/8];
+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(mFDs[id_to_index(device->id)].fd,
+    if (ioctl(device->fd,
                EVIOCGKEY(sizeof(key_bitmask)), key_bitmask) >= 0) {
+        return test_bit(scanCode, key_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
+    AutoMutex _l(mLock);
+
+    device_t* device = getDeviceLocked(deviceId);
+    if (device != NULL) {
+        return getKeyCodeStateLocked(device, keyCode);
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getKeyCodeStateLocked(device_t* device, int32_t keyCode) const {
+    Vector<int32_t> scanCodes;
+    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
         for (size_t i=0; i<=KEY_MAX; i++) {
             LOGI("(Scan code %d: down=%d)", i, test_bit(i, key_bitmask));
@@ -239,19 +220,79 @@
             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 = getDeviceLocked(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 = getDeviceLocked(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,
         int32_t* outKeycode, uint32_t* outFlags) const
 {
     AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
+    device_t* device = getDeviceLocked(deviceId);
     
     if (device != NULL && device->layoutMap != NULL) {
         status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
@@ -261,7 +302,7 @@
     }
     
     if (mHaveFirstKeyboard) {
-        device = getDevice(mFirstKeyboardId);
+        device = getDeviceLocked(mFirstKeyboardId);
         
         if (device != NULL && device->layoutMap != NULL) {
             status_t err = device->layoutMap->map(scancode, outKeycode, outFlags);
@@ -278,11 +319,13 @@
 
 void EventHub::addExcludedDevice(const char* deviceName)
 {
+    AutoMutex _l(mLock);
+
     String8 name(deviceName);
     mExcludedDevices.push_back(name);
 }
 
-EventHub::device_t* EventHub::getDevice(int32_t deviceId) const
+EventHub::device_t* EventHub::getDeviceLocked(int32_t deviceId) const
 {
     if (deviceId == 0) deviceId = mFirstKeyboardId;
     int32_t id = deviceId & ID_MASK;
@@ -295,27 +338,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.
@@ -323,94 +354,145 @@
     if (!mOpened) {
         mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR;
         mOpened = true;
+        mNeedToSendFinishedDeviceScan = 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;
+            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
             delete device;
+            mNeedToSendFinishedDeviceScan = true;
             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;
+            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
+            mNeedToSendFinishedDeviceScan = true;
             return true;
         }
 
-        release_wake_lock(WAKE_LOCK_ID);
-
-        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;
+        if (mNeedToSendFinishedDeviceScan) {
+            mNeedToSendFinishedDeviceScan = false;
+            outEvent->type = FINISHED_DEVICE_SCAN;
+            outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
+            return true;
         }
 
-        //printf("poll %d, returned %d\n", mFDCount, pollres);
+        // 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];
 
-        // 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) {
+                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
+
+#if HAVE_INOTIFY
+        // readNotify() 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);
+            readNotify(mFDs[0].fd);
+            mFDs[0].revents = 0;
+            continue; // report added or removed devices immediately
+        }
+#endif
+
+        mInputDeviceIndex = 0;
+
+        // 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("poll failed (errno=%d)\n", errno);
+                usleep(100000);
+            }
         }
     }
 }
@@ -429,6 +511,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();
@@ -444,40 +527,9 @@
     mFDs[0].fd = -1;
 #endif
 
-    res = scan_dir(device_path);
+    res = scanDir(device_path);
     if(res < 0) {
         LOGE("scan dir failed for %s\n", device_path);
-        //open_device("/dev/input/event0");
-    }
-
-    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;
-                        }
-                    }
-                }
-            }
-        }
     }
 
     return true;
@@ -485,8 +537,27 @@
 
 // ----------------------------------------------------------------------------
 
-int EventHub::open_device(const char *deviceName)
-{
+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 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::openDevice(const char *deviceName) {
     int version;
     int fd;
     struct pollfd *new_mFDs;
@@ -531,7 +602,6 @@
         if (strcmp(name, test) == 0) {
             LOGI("ignoring event id %s driver %s\n", deviceName, test);
             close(fd);
-            fd = -1;
             return -1;
         }
     }
@@ -545,6 +615,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) {
@@ -599,30 +675,32 @@
         return -1;
     }
 
+    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));
@@ -634,53 +712,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];
 
@@ -702,7 +784,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")) {
@@ -722,23 +807,39 @@
         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 (hasKeycodeLocked(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 (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) &&
+                hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) &&
+                hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) &&
+                hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) &&
+                hasKeycodeLocked(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)/sizeof(GAMEPAD_KEYCODES[0]); i++) {
+            if (hasKeycodeLocked(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);
     }
 
+    // If the device isn't recognized as something we handle, don't monitor it.
+    if (device->classes == 0) {
+        LOGV("Dropping device %s %p, id = %d\n", deviceName, device, devid);
+        close(fd);
+        delete device;
+        return -1;
+    }
+
     LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
          deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
          
@@ -754,7 +855,7 @@
     return 0;
 }
 
-bool EventHub::hasKeycode(device_t* device, int keycode) const
+bool EventHub::hasKeycodeLocked(device_t* device, int keycode) const
 {
     if (device->keyBitmask == NULL || device->layoutMap == NULL) {
         return false;
@@ -773,10 +874,9 @@
     return false;
 }
 
-int EventHub::close_device(const char *deviceName)
-{
+int EventHub::closeDevice(const char *deviceName) {
     AutoMutex _l(mLock);
-    
+
     int i;
     for(i = 1; i < mFDCount; i++) {
         if(strcmp(mDevices[i]->path.string(), deviceName) == 0) {
@@ -826,8 +926,7 @@
     return -1;
 }
 
-int EventHub::read_notify(int nfd)
-{
+int EventHub::readNotify(int nfd) {
 #ifdef HAVE_INOTIFY
     int res;
     char devname[PATH_MAX];
@@ -837,7 +936,7 @@
     int event_pos = 0;
     struct inotify_event *event;
 
-    LOGV("EventHub::read_notify nfd: %d\n", nfd);
+    LOGV("EventHub::readNotify nfd: %d\n", nfd);
     res = read(nfd, event_buf, sizeof(event_buf));
     if(res < (int)sizeof(*event)) {
         if(errno == EINTR)
@@ -857,10 +956,10 @@
         if(event->len) {
             strcpy(filename, event->name);
             if(event->mask & IN_CREATE) {
-                open_device(devname);
+                openDevice(devname);
             }
             else {
-                close_device(devname);
+                closeDevice(devname);
             }
         }
         event_size = sizeof(*event) + event->len;
@@ -872,7 +971,7 @@
 }
 
 
-int EventHub::scan_dir(const char *dirname)
+int EventHub::scanDir(const char *dirname)
 {
     char devname[PATH_MAX];
     char *filename;
@@ -890,10 +989,38 @@
             (de->d_name[1] == '.' && de->d_name[2] == '\0')))
             continue;
         strcpy(filename, de->d_name);
-        open_device(devname);
+        openDevice(devname);
     }
     closedir(dir);
     return 0;
 }
 
+void EventHub::dump(String8& dump) {
+    dump.append("Event Hub State:\n");
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        dump.appendFormat(INDENT "HaveFirstKeyboard: %s\n", toString(mHaveFirstKeyboard));
+        dump.appendFormat(INDENT "FirstKeyboardId: 0x%x\n", mFirstKeyboardId);
+
+        dump.append(INDENT "Devices:\n");
+
+        for (int i = 0; i < mNumDevicesById; i++) {
+            const device_t* device = mDevicesById[i].device;
+            if (device) {
+                if (mFirstKeyboardId == device->id) {
+                    dump.appendFormat(INDENT2 "0x%x: %s (aka device 0 - first keyboard)\n",
+                            device->id, device->name.string());
+                } else {
+                    dump.appendFormat(INDENT2 "0x%x: %s\n", device->id, device->name.string());
+                }
+                dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes);
+                dump.appendFormat(INDENT3 "Path: %s\n", device->path.string());
+                dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n", device->keylayoutFilename.string());
+            }
+        }
+    } // release lock
+}
+
 }; // namespace android
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 52380a0..a36d555 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -29,6 +29,7 @@
 
 #include <ui/Rect.h>
 #include <ui/FramebufferNativeWindow.h>
+#include <ui/GraphicLog.h>
 
 #include <EGL/egl.h>
 
@@ -67,7 +68,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 +118,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,63 +169,91 @@
 }
 
 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, 
+// only for debugging / logging
+int FramebufferNativeWindow::getCurrentBufferIndex() const
+{
+    Mutex::Autolock _l(mutex);
+    const int index = mCurrentBufferIndex;
+    return index;
+}
+
+int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window, 
         android_native_buffer_t** buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
     framebuffer_device_t* fb = self->fbDev;
 
+    int index = self->mBufferHead++;
+    if (self->mBufferHead >= self->mNumBuffers)
+        self->mBufferHead = 0;
+
+    GraphicLog& logger(GraphicLog::getInstance());
+    logger.log(GraphicLog::SF_FB_DEQUEUE_BEFORE, index);
+
     // wait for a free buffer
     while (!self->mNumFreeBuffers) {
         self->mCondition.wait(self->mutex);
     }
     // get this buffer
     self->mNumFreeBuffers--;
-    int index = self->mBufferHead++;
-    if (self->mBufferHead >= self->mNumBuffers)
-        self->mBufferHead = 0;
+    self->mCurrentBufferIndex = index;
 
     *buffer = self->buffers[index].get();
 
+    logger.log(GraphicLog::SF_FB_DEQUEUE_AFTER, index);
     return 0;
 }
 
-int FramebufferNativeWindow::lockBuffer(android_native_window_t* window, 
+int FramebufferNativeWindow::lockBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer)
 {
     FramebufferNativeWindow* self = getSelf(window);
     Mutex::Autolock _l(self->mutex);
 
+    const int index = self->mCurrentBufferIndex;
+    GraphicLog& logger(GraphicLog::getInstance());
+    logger.log(GraphicLog::SF_FB_LOCK_BEFORE, index);
+
     // wait that the buffer we're locking is not front anymore
     while (self->front == buffer) {
         self->mCondition.wait(self->mutex);
     }
 
+    logger.log(GraphicLog::SF_FB_LOCK_AFTER, index);
+
     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);
     Mutex::Autolock _l(self->mutex);
     framebuffer_device_t* fb = self->fbDev;
     buffer_handle_t handle = static_cast<NativeBuffer*>(buffer)->handle;
+
+    const int index = self->mCurrentBufferIndex;
+    GraphicLog& logger(GraphicLog::getInstance());
+    logger.log(GraphicLog::SF_FB_POST_BEFORE, index);
+
     int res = fb->post(fb, handle);
+
+    logger.log(GraphicLog::SF_FB_POST_AFTER, index);
+
     self->front = static_cast<NativeBuffer*>(buffer);
     self->mNumFreeBuffers++;
     self->mCondition.broadcast();
     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 +274,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/GraphicLog.cpp b/libs/ui/GraphicLog.cpp
new file mode 100644
index 0000000..7ba2779
--- /dev/null
+++ b/libs/ui/GraphicLog.cpp
@@ -0,0 +1,92 @@
+/*
+ * 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 <unistd.h>
+#include <cutils/log.h>
+#include <cutils/properties.h>
+#include <utils/Endian.h>
+#include <utils/Timers.h>
+
+#include <ui/GraphicLog.h>
+
+namespace android {
+
+ANDROID_SINGLETON_STATIC_INSTANCE(GraphicLog)
+
+static inline
+void writeInt32(uint8_t* base, size_t& pos, int32_t value) {
+#ifdef HAVE_LITTLE_ENDIAN
+    int32_t v = value;
+#else
+    int32_t v = htole32(value);
+#endif
+    base[pos] = EVENT_TYPE_INT;
+    memcpy(&base[pos+1], &v, sizeof(int32_t));
+    pos += 1+sizeof(int32_t);
+}
+
+static inline
+void writeInt64(uint8_t* base,  size_t& pos, int64_t value) {
+#ifdef HAVE_LITTLE_ENDIAN
+    int64_t v = value;
+#else
+    int64_t v = htole64(value);
+#endif
+    base[pos] = EVENT_TYPE_LONG;
+    memcpy(&base[pos+1], &v, sizeof(int64_t));
+    pos += 1+sizeof(int64_t);
+}
+
+void GraphicLog::logImpl(int32_t tag, int32_t buffer)
+{
+    uint8_t scratch[2 + 2 + sizeof(int32_t) + sizeof(int64_t)];
+    size_t pos = 0;
+    scratch[pos++] = EVENT_TYPE_LIST;
+    scratch[pos++] = 2;
+    writeInt32(scratch, pos, buffer);
+    writeInt64(scratch, pos, ns2ms( systemTime( SYSTEM_TIME_MONOTONIC ) ));
+    android_bWriteLog(tag, scratch, sizeof(scratch));
+}
+
+void GraphicLog::logImpl(int32_t tag, int32_t identity, int32_t buffer)
+{
+    uint8_t scratch[2 + 3 + sizeof(int32_t) + sizeof(int32_t) + sizeof(int64_t)];
+    size_t pos = 0;
+    scratch[pos++] = EVENT_TYPE_LIST;
+    scratch[pos++] = 3;
+    writeInt32(scratch, pos, buffer);
+    writeInt32(scratch, pos, identity);
+    writeInt64(scratch, pos, ns2ms( systemTime( SYSTEM_TIME_MONOTONIC ) ));
+    android_bWriteLog(tag, scratch, sizeof(scratch));
+}
+
+GraphicLog::GraphicLog()
+    : mEnabled(0)
+{
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("debug.graphic_log", property, NULL) > 0) {
+        mEnabled = atoi(property);
+    }
+}
+
+void GraphicLog::setEnabled(bool enable)
+{
+    mEnabled = enable;
+}
+
+}
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..28ccc43
--- /dev/null
+++ b/libs/ui/InputDispatcher.cpp
@@ -0,0 +1,3504 @@
+//
+// 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
+
+// Log debug messages about input focus tracking.
+#define DEBUG_FOCUS 0
+
+// Log debug messages about the app switch latency optimization.
+#define DEBUG_APP_SWITCH 0
+
+#include <cutils/log.h>
+#include <ui/InputDispatcher.h>
+#include <ui/PowerManager.h>
+
+#include <stddef.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+
+#define INDENT "  "
+#define INDENT2 "    "
+
+namespace android {
+
+// Delay before reporting long touch events to the power manager.
+const nsecs_t LONG_TOUCH_DELAY = 300 * 1000000LL; // 300 ms
+
+// Default input dispatching timeout if there is no focused application or paused window
+// from which to determine an appropriate dispatching timeout.
+const nsecs_t DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5000 * 1000000LL; // 5 sec
+
+// Amount of time to allow for all pending events to be processed when an app switch
+// key is on the way.  This is used to preempt input dispatch and drop input events
+// when an application takes too long to respond and the user has pressed an app switch key.
+const nsecs_t APP_SWITCH_TIMEOUT = 500 * 1000000LL; // 0.5sec
+
+
+static inline nsecs_t now() {
+    return systemTime(SYSTEM_TIME_MONOTONIC);
+}
+
+static inline const char* toString(bool value) {
+    return value ? "true" : "false";
+}
+
+static inline int32_t getMotionEventActionPointerIndex(int32_t action) {
+    return (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK)
+            >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+}
+
+static bool isValidKeyAction(int32_t action) {
+    switch (action) {
+    case AKEY_EVENT_ACTION_DOWN:
+    case AKEY_EVENT_ACTION_UP:
+        return true;
+    default:
+        return false;
+    }
+}
+
+static bool validateKeyEvent(int32_t action) {
+    if (! isValidKeyAction(action)) {
+        LOGE("Key event has invalid action code 0x%x", action);
+        return false;
+    }
+    return true;
+}
+
+static bool isValidMotionAction(int32_t action, size_t pointerCount) {
+    switch (action & AMOTION_EVENT_ACTION_MASK) {
+    case AMOTION_EVENT_ACTION_DOWN:
+    case AMOTION_EVENT_ACTION_UP:
+    case AMOTION_EVENT_ACTION_CANCEL:
+    case AMOTION_EVENT_ACTION_MOVE:
+    case AMOTION_EVENT_ACTION_OUTSIDE:
+        return true;
+    case AMOTION_EVENT_ACTION_POINTER_DOWN:
+    case AMOTION_EVENT_ACTION_POINTER_UP: {
+        int32_t index = getMotionEventActionPointerIndex(action);
+        return index >= 0 && size_t(index) < pointerCount;
+    }
+    default:
+        return false;
+    }
+}
+
+static bool validateMotionEvent(int32_t action, size_t pointerCount,
+        const int32_t* pointerIds) {
+    if (! isValidMotionAction(action, pointerCount)) {
+        LOGE("Motion event has invalid action code 0x%x", action);
+        return false;
+    }
+    if (pointerCount < 1 || pointerCount > MAX_POINTERS) {
+        LOGE("Motion event has invalid pointer count %d; value must be between 1 and %d.",
+                pointerCount, MAX_POINTERS);
+        return false;
+    }
+    BitSet32 pointerIdBits;
+    for (size_t i = 0; i < pointerCount; i++) {
+        int32_t id = pointerIds[i];
+        if (id < 0 || id > MAX_POINTER_ID) {
+            LOGE("Motion event has invalid pointer id %d; value must be between 0 and %d",
+                    id, MAX_POINTER_ID);
+            return false;
+        }
+        if (pointerIdBits.hasBit(id)) {
+            LOGE("Motion event has duplicate pointer id %d", id);
+            return false;
+        }
+        pointerIdBits.markBit(id);
+    }
+    return true;
+}
+
+
+// --- InputWindow ---
+
+bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
+    return x >= touchableAreaLeft && x <= touchableAreaRight
+            && y >= touchableAreaTop && y <= touchableAreaBottom;
+}
+
+bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
+    return x >= frameLeft && x <= frameRight
+            && y >= frameTop && y <= frameBottom;
+}
+
+bool InputWindow::isTrustedOverlay() const {
+    return layoutParamsType == TYPE_INPUT_METHOD
+            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG
+            || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
+}
+
+
+// --- InputDispatcher ---
+
+InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
+    mPolicy(policy),
+    mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
+    mDispatchEnabled(true), mDispatchFrozen(false),
+    mFocusedWindow(NULL),
+    mFocusedApplication(NULL),
+    mCurrentInputTargetsValid(false),
+    mInputTargetWaitCause(INPUT_TARGET_WAIT_CAUSE_NONE) {
+    mLooper = new Looper(false);
+
+    mInboundQueue.headSentinel.refCount = -1;
+    mInboundQueue.headSentinel.type = EventEntry::TYPE_SENTINEL;
+    mInboundQueue.headSentinel.eventTime = LONG_LONG_MIN;
+
+    mInboundQueue.tailSentinel.refCount = -1;
+    mInboundQueue.tailSentinel.type = EventEntry::TYPE_SENTINEL;
+    mInboundQueue.tailSentinel.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
+}
+
+InputDispatcher::~InputDispatcher() {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        resetKeyRepeatLocked();
+        releasePendingEventLocked();
+        drainInboundQueueLocked();
+    }
+
+    while (mConnectionsByReceiveFd.size() != 0) {
+        unregisterInputChannel(mConnectionsByReceiveFd.valueAt(0)->inputChannel);
+    }
+}
+
+void InputDispatcher::dispatchOnce() {
+    nsecs_t keyRepeatTimeout = mPolicy->getKeyRepeatTimeout();
+    nsecs_t keyRepeatDelay = mPolicy->getKeyRepeatDelay();
+
+    nsecs_t nextWakeupTime = LONG_LONG_MAX;
+    { // acquire lock
+        AutoMutex _l(mLock);
+        dispatchOnceInnerLocked(keyRepeatTimeout, keyRepeatDelay, & nextWakeupTime);
+
+        if (runCommandsLockedInterruptible()) {
+            nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
+        }
+    } // release lock
+
+    // Wait for callback or timeout or wake.  (make sure we round up, not down)
+    nsecs_t currentTime = now();
+    int32_t timeoutMillis;
+    if (nextWakeupTime > currentTime) {
+        uint64_t timeout = uint64_t(nextWakeupTime - currentTime);
+        timeout = (timeout + 999999LL) / 1000000LL;
+        timeoutMillis = timeout > INT_MAX ? -1 : int32_t(timeout);
+    } else {
+        timeoutMillis = 0;
+    }
+
+    mLooper->pollOnce(timeoutMillis);
+}
+
+void InputDispatcher::dispatchOnceInnerLocked(nsecs_t keyRepeatTimeout,
+        nsecs_t keyRepeatDelay, nsecs_t* nextWakeupTime) {
+    nsecs_t 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.
+    if (keyRepeatTimeout < 0) {
+        resetKeyRepeatLocked();
+    }
+
+    // If dispatching is frozen, do not process timeouts or try to deliver any new events.
+    if (mDispatchFrozen) {
+#if DEBUG_FOCUS
+        LOGD("Dispatch frozen.  Waiting some more.");
+#endif
+        return;
+    }
+
+    // Optimize latency of app switches.
+    // Essentially we start a short timeout when an app switch key (HOME / ENDCALL) has
+    // been pressed.  When it expires, we preempt dispatch and drop all other pending events.
+    bool isAppSwitchDue = mAppSwitchDueTime <= currentTime;
+    if (mAppSwitchDueTime < *nextWakeupTime) {
+        *nextWakeupTime = mAppSwitchDueTime;
+    }
+
+    // Ready to start a new event.
+    // If we don't already have a pending event, go grab one.
+    if (! mPendingEvent) {
+        if (mInboundQueue.isEmpty()) {
+            if (isAppSwitchDue) {
+                // The inbound queue is empty so the app switch key we were waiting
+                // for will never arrive.  Stop waiting for it.
+                resetPendingAppSwitchLocked(false);
+                isAppSwitchDue = false;
+            }
+
+            // Synthesize a key repeat if appropriate.
+            if (mKeyRepeatState.lastKeyEntry) {
+                if (currentTime >= mKeyRepeatState.nextRepeatTime) {
+                    mPendingEvent = synthesizeKeyRepeatLocked(currentTime, keyRepeatDelay);
+                } else {
+                    if (mKeyRepeatState.nextRepeatTime < *nextWakeupTime) {
+                        *nextWakeupTime = mKeyRepeatState.nextRepeatTime;
+                    }
+                }
+            }
+            if (! mPendingEvent) {
+                return;
+            }
+        } else {
+            // Inbound queue has at least one entry.
+            EventEntry* entry = mInboundQueue.headSentinel.next;
+
+            // Throttle 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
+                    && !isAppSwitchDue
+                    && mDispatchEnabled
+                    && (entry->policyFlags & POLICY_FLAG_PASS_TO_USER)
+                    && !entry->isInjected()) {
+                MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+                int32_t deviceId = motionEntry->deviceId;
+                uint32_t source = motionEntry->source;
+                if (! isAppSwitchDue
+                        && motionEntry->next == & mInboundQueue.tailSentinel // exactly one event
+                        && 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();
+                        }
+                        return;
+                    }
+                }
+
+#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;
+            }
+
+            mInboundQueue.dequeue(entry);
+            mPendingEvent = entry;
+        }
+
+        // Poke user activity for this event.
+        if (mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER) {
+            pokeUserActivityLocked(mPendingEvent);
+        }
+    }
+
+    // Now we have an event to dispatch.
+    assert(mPendingEvent != NULL);
+    bool done = false;
+    DropReason dropReason = DROP_REASON_NOT_DROPPED;
+    if (!(mPendingEvent->policyFlags & POLICY_FLAG_PASS_TO_USER)) {
+        dropReason = DROP_REASON_POLICY;
+    } else if (!mDispatchEnabled) {
+        dropReason = DROP_REASON_DISABLED;
+    }
+    switch (mPendingEvent->type) {
+    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
+        ConfigurationChangedEntry* typedEntry =
+                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
+        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
+        dropReason = DROP_REASON_NOT_DROPPED; // configuration changes are never dropped
+        break;
+    }
+
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
+        if (isAppSwitchDue) {
+            if (isAppSwitchKeyEventLocked(typedEntry)) {
+                resetPendingAppSwitchLocked(true);
+                isAppSwitchDue = false;
+            } else if (dropReason == DROP_REASON_NOT_DROPPED) {
+                dropReason = DROP_REASON_APP_SWITCH;
+            }
+        }
+        done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout,
+                &dropReason, nextWakeupTime);
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
+        if (dropReason == DROP_REASON_NOT_DROPPED && isAppSwitchDue) {
+            dropReason = DROP_REASON_APP_SWITCH;
+        }
+        done = dispatchMotionLocked(currentTime, typedEntry,
+                &dropReason, nextWakeupTime);
+        break;
+    }
+
+    default:
+        assert(false);
+        break;
+    }
+
+    if (done) {
+        if (dropReason != DROP_REASON_NOT_DROPPED) {
+            dropInboundEventLocked(mPendingEvent, dropReason);
+        }
+
+        releasePendingEventLocked();
+        *nextWakeupTime = LONG_LONG_MIN;  // force next poll to wake up immediately
+    }
+}
+
+bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) {
+    bool needWake = mInboundQueue.isEmpty();
+    mInboundQueue.enqueueAtTail(entry);
+
+    switch (entry->type) {
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* keyEntry = static_cast<KeyEntry*>(entry);
+        if (isAppSwitchKeyEventLocked(keyEntry)) {
+            if (keyEntry->action == AKEY_EVENT_ACTION_DOWN) {
+                mAppSwitchSawKeyDown = true;
+            } else if (keyEntry->action == AKEY_EVENT_ACTION_UP) {
+                if (mAppSwitchSawKeyDown) {
+#if DEBUG_APP_SWITCH
+                    LOGD("App switch is pending!");
+#endif
+                    mAppSwitchDueTime = keyEntry->eventTime + APP_SWITCH_TIMEOUT;
+                    mAppSwitchSawKeyDown = false;
+                    needWake = true;
+                }
+            }
+        }
+        break;
+    }
+    }
+
+    return needWake;
+}
+
+void InputDispatcher::dropInboundEventLocked(EventEntry* entry, DropReason dropReason) {
+    const char* reason;
+    switch (dropReason) {
+    case DROP_REASON_POLICY:
+#if DEBUG_INBOUND_EVENT_DETAILS
+        LOGD("Dropped event because policy consumed it.");
+#endif
+        reason = "inbound event was dropped because the policy consumed it";
+        break;
+    case DROP_REASON_DISABLED:
+        LOGI("Dropped event because input dispatch is disabled.");
+        reason = "inbound event was dropped because input dispatch is disabled";
+        break;
+    case DROP_REASON_APP_SWITCH:
+        LOGI("Dropped event because of pending overdue app switch.");
+        reason = "inbound event was dropped because of pending overdue app switch";
+        break;
+    default:
+        assert(false);
+        return;
+    }
+
+    switch (entry->type) {
+    case EventEntry::TYPE_KEY:
+        synthesizeCancelationEventsForAllConnectionsLocked(
+                InputState::CANCEL_NON_POINTER_EVENTS, reason);
+        break;
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(entry);
+        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+            synthesizeCancelationEventsForAllConnectionsLocked(
+                    InputState::CANCEL_POINTER_EVENTS, reason);
+        } else {
+            synthesizeCancelationEventsForAllConnectionsLocked(
+                    InputState::CANCEL_NON_POINTER_EVENTS, reason);
+        }
+        break;
+    }
+    }
+}
+
+bool InputDispatcher::isAppSwitchKeyCode(int32_t keyCode) {
+    return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
+}
+
+bool InputDispatcher::isAppSwitchKeyEventLocked(KeyEntry* keyEntry) {
+    return ! (keyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
+            && isAppSwitchKeyCode(keyEntry->keyCode)
+            && (keyEntry->policyFlags & POLICY_FLAG_TRUSTED)
+            && (keyEntry->policyFlags & POLICY_FLAG_PASS_TO_USER);
+}
+
+bool InputDispatcher::isAppSwitchPendingLocked() {
+    return mAppSwitchDueTime != LONG_LONG_MAX;
+}
+
+void InputDispatcher::resetPendingAppSwitchLocked(bool handled) {
+    mAppSwitchDueTime = LONG_LONG_MAX;
+
+#if DEBUG_APP_SWITCH
+    if (handled) {
+        LOGD("App switch has arrived.");
+    } else {
+        LOGD("App switch was abandoned.");
+    }
+#endif
+}
+
+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::drainInboundQueueLocked() {
+    while (! mInboundQueue.isEmpty()) {
+        EventEntry* entry = mInboundQueue.dequeueAtHead();
+        releaseInboundEventLocked(entry);
+    }
+}
+
+void InputDispatcher::releasePendingEventLocked() {
+    if (mPendingEvent) {
+        releaseInboundEventLocked(mPendingEvent);
+        mPendingEvent = NULL;
+    }
+}
+
+void InputDispatcher::releaseInboundEventLocked(EventEntry* entry) {
+    InjectionState* injectionState = entry->injectionState;
+    if (injectionState && injectionState->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("Injected inbound event was dropped.");
+#endif
+        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+    }
+    mAllocator.releaseEventEntry(entry);
+}
+
+void InputDispatcher::resetKeyRepeatLocked() {
+    if (mKeyRepeatState.lastKeyEntry) {
+        mAllocator.releaseKeyEntry(mKeyRepeatState.lastKeyEntry);
+        mKeyRepeatState.lastKeyEntry = NULL;
+    }
+}
+
+InputDispatcher::KeyEntry* InputDispatcher::synthesizeKeyRepeatLocked(
+        nsecs_t currentTime, nsecs_t keyRepeatDelay) {
+    KeyEntry* entry = mKeyRepeatState.lastKeyEntry;
+
+    // Reuse the repeated key entry if it is otherwise unreferenced.
+    uint32_t policyFlags = (entry->policyFlags & POLICY_FLAG_RAW_MASK)
+            | POLICY_FLAG_PASS_TO_USER | POLICY_FLAG_TRUSTED;
+    if (entry->refCount == 1) {
+        mAllocator.recycleKeyEntry(entry);
+        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;
+    }
+    entry->syntheticRepeat = true;
+
+    // Increment reference count since we keep a reference to the event in
+    // mKeyRepeatState.lastKeyEntry in addition to the one we return.
+    entry->refCount += 1;
+
+    if (entry->repeatCount == 1) {
+        entry->flags |= AKEY_EVENT_FLAG_LONG_PRESS;
+    }
+
+    mKeyRepeatState.nextRepeatTime = currentTime + keyRepeatDelay;
+    return entry;
+}
+
+bool InputDispatcher::dispatchConfigurationChangedLocked(
+        nsecs_t currentTime, ConfigurationChangedEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("dispatchConfigurationChanged - eventTime=%lld", entry->eventTime);
+#endif
+
+    // Reset key repeating in case a keyboard device was added or removed or something.
+    resetKeyRepeatLocked();
+
+    // Enqueue a command to run outside the lock to tell the policy that the configuration changed.
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doNotifyConfigurationChangedInterruptible);
+    commandEntry->eventTime = entry->eventTime;
+    return true;
+}
+
+bool InputDispatcher::dispatchKeyLocked(
+        nsecs_t currentTime, KeyEntry* entry, nsecs_t keyRepeatTimeout,
+        DropReason* dropReason, nsecs_t* nextWakeupTime) {
+    // Preprocessing.
+    if (! entry->dispatchInProgress) {
+        if (entry->repeatCount == 0
+                && entry->action == AKEY_EVENT_ACTION_DOWN
+                && (entry->policyFlags & POLICY_FLAG_TRUSTED)
+                && !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 if (! entry->syntheticRepeat) {
+            resetKeyRepeatLocked();
+        }
+
+        entry->dispatchInProgress = true;
+        resetTargetsLocked();
+
+        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
+    }
+
+    // Give the policy a chance to intercept the key.
+    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
+        if (entry->policyFlags & POLICY_FLAG_PASS_TO_USER) {
+            CommandEntry* commandEntry = postCommandLocked(
+                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
+            if (mFocusedWindow) {
+                commandEntry->inputChannel = mFocusedWindow->inputChannel;
+            }
+            commandEntry->keyEntry = entry;
+            entry->refCount += 1;
+            return false; // wait for the command to run
+        } else {
+            entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
+        }
+    } else if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_SKIP) {
+        if (*dropReason == DROP_REASON_NOT_DROPPED) {
+            *dropReason = DROP_REASON_POLICY;
+        }
+    }
+
+    // Clean up if dropping the event.
+    if (*dropReason != DROP_REASON_NOT_DROPPED) {
+        resetTargetsLocked();
+        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
+        return true;
+    }
+
+    // Identify targets.
+    if (! mCurrentInputTargetsValid) {
+        int32_t injectionResult = findFocusedWindowTargetsLocked(currentTime,
+                entry, nextWakeupTime);
+        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+            return false;
+        }
+
+        setInjectionResultLocked(entry, injectionResult);
+        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+            return true;
+        }
+
+        addMonitoringTargetsLocked();
+        commitTargetsLocked();
+    }
+
+    // Dispatch the key.
+    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+    return true;
+}
+
+void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("%seventTime=%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",
+            prefix,
+            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
+            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
+            entry->repeatCount, entry->downTime);
+#endif
+}
+
+bool InputDispatcher::dispatchMotionLocked(
+        nsecs_t currentTime, MotionEntry* entry, DropReason* dropReason, nsecs_t* nextWakeupTime) {
+    // Preprocessing.
+    if (! entry->dispatchInProgress) {
+        entry->dispatchInProgress = true;
+        resetTargetsLocked();
+
+        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
+    }
+
+    // Clean up if dropping the event.
+    if (*dropReason != DROP_REASON_NOT_DROPPED) {
+        resetTargetsLocked();
+        setInjectionResultLocked(entry, *dropReason == DROP_REASON_POLICY
+                ? INPUT_EVENT_INJECTION_SUCCEEDED : INPUT_EVENT_INJECTION_FAILED);
+        return true;
+    }
+
+    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
+
+    // Identify targets.
+    if (! mCurrentInputTargetsValid) {
+        int32_t injectionResult;
+        if (isPointerEvent) {
+            // Pointer event.  (eg. touchscreen)
+            injectionResult = findTouchedWindowTargetsLocked(currentTime,
+                    entry, nextWakeupTime);
+        } else {
+            // Non touch event.  (eg. trackball)
+            injectionResult = findFocusedWindowTargetsLocked(currentTime,
+                    entry, nextWakeupTime);
+        }
+        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+            return false;
+        }
+
+        setInjectionResultLocked(entry, injectionResult);
+        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+            return true;
+        }
+
+        addMonitoringTargetsLocked();
+        commitTargetsLocked();
+    }
+
+    // Dispatch the motion.
+    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+    return true;
+}
+
+
+void InputDispatcher::logOutboundMotionDetailsLocked(const char* prefix, const MotionEntry* entry) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+    LOGD("%seventTime=%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",
+            prefix,
+            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;
+    const 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
+}
+
+void InputDispatcher::dispatchEventToCurrentInputTargetsLocked(nsecs_t currentTime,
+        EventEntry* eventEntry, bool resumeWithAppendedMotionSample) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("dispatchEventToCurrentInputTargets - "
+            "resumeWithAppendedMotionSample=%s",
+            toString(resumeWithAppendedMotionSample));
+#endif
+
+    assert(eventEntry->dispatchInProgress); // should already have been set to true
+
+    pokeUserActivityLocked(eventEntry);
+
+    for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
+        const InputTarget& inputTarget = mCurrentInputTargets.itemAt(i);
+
+        ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
+        if (connectionIndex >= 0) {
+            sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+            prepareDispatchCycleLocked(currentTime, connection, eventEntry, & inputTarget,
+                    resumeWithAppendedMotionSample);
+        } else {
+#if DEBUG_FOCUS
+            LOGD("Dropping event delivery to target with channel '%s' because it "
+                    "is no longer registered with the input dispatcher.",
+                    inputTarget.inputChannel->getName().string());
+#endif
+        }
+    }
+}
+
+void InputDispatcher::resetTargetsLocked() {
+    mCurrentInputTargetsValid = false;
+    mCurrentInputTargets.clear();
+    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
+}
+
+void InputDispatcher::commitTargetsLocked() {
+    mCurrentInputTargetsValid = true;
+}
+
+int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
+        const EventEntry* entry, const InputApplication* application, const InputWindow* window,
+        nsecs_t* nextWakeupTime) {
+    if (application == NULL && window == NULL) {
+        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
+#if DEBUG_FOCUS
+            LOGD("Waiting for system to become ready for input.");
+#endif
+            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
+            mInputTargetWaitStartTime = currentTime;
+            mInputTargetWaitTimeoutTime = LONG_LONG_MAX;
+            mInputTargetWaitTimeoutExpired = false;
+        }
+    } else {
+        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
+#if DEBUG_FOCUS
+            LOGD("Waiting for application to become ready for input: %s",
+                    getApplicationWindowLabelLocked(application, window).string());
+#endif
+            nsecs_t timeout = window ? window->dispatchingTimeout :
+                application ? application->dispatchingTimeout : DEFAULT_INPUT_DISPATCHING_TIMEOUT;
+
+            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY;
+            mInputTargetWaitStartTime = currentTime;
+            mInputTargetWaitTimeoutTime = currentTime + timeout;
+            mInputTargetWaitTimeoutExpired = false;
+        }
+    }
+
+    if (mInputTargetWaitTimeoutExpired) {
+        return INPUT_EVENT_INJECTION_TIMED_OUT;
+    }
+
+    if (currentTime >= mInputTargetWaitTimeoutTime) {
+        onANRLocked(currentTime, application, window, entry->eventTime, mInputTargetWaitStartTime);
+
+        // Force poll loop to wake up immediately on next iteration once we get the
+        // ANR response back from the policy.
+        *nextWakeupTime = LONG_LONG_MIN;
+        return INPUT_EVENT_INJECTION_PENDING;
+    } else {
+        // Force poll loop to wake up when timeout is due.
+        if (mInputTargetWaitTimeoutTime < *nextWakeupTime) {
+            *nextWakeupTime = mInputTargetWaitTimeoutTime;
+        }
+        return INPUT_EVENT_INJECTION_PENDING;
+    }
+}
+
+void InputDispatcher::resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
+        const sp<InputChannel>& inputChannel) {
+    if (newTimeout > 0) {
+        // Extend the timeout.
+        mInputTargetWaitTimeoutTime = now() + newTimeout;
+    } else {
+        // Give up.
+        mInputTargetWaitTimeoutExpired = true;
+
+        // Release the touch targets.
+        mTouchState.reset();
+
+        // Input state will not be realistic.  Mark it out of sync.
+        if (inputChannel.get()) {
+            ssize_t connectionIndex = getConnectionIndexLocked(inputChannel);
+            if (connectionIndex >= 0) {
+                sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+                synthesizeCancelationEventsForConnectionLocked(
+                        connection, InputState::CANCEL_ALL_EVENTS,
+                        "application not responding");
+            }
+        }
+    }
+}
+
+nsecs_t InputDispatcher::getTimeSpentWaitingForApplicationLocked(
+        nsecs_t currentTime) {
+    if (mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
+        return currentTime - mInputTargetWaitStartTime;
+    }
+    return 0;
+}
+
+void InputDispatcher::resetANRTimeoutsLocked() {
+#if DEBUG_FOCUS
+        LOGD("Resetting ANR timeouts.");
+#endif
+
+    // Reset input target wait timeout.
+    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
+}
+
+int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
+        const EventEntry* entry, nsecs_t* nextWakeupTime) {
+    mCurrentInputTargets.clear();
+
+    int32_t injectionResult;
+
+    // If there is no currently focused window and no focused application
+    // then drop the event.
+    if (! mFocusedWindow) {
+        if (mFocusedApplication) {
+#if DEBUG_FOCUS
+            LOGD("Waiting because there is no focused window but there is a "
+                    "focused application that may eventually add a window: %s.",
+                    getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
+#endif
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    mFocusedApplication, NULL, nextWakeupTime);
+            goto Unresponsive;
+        }
+
+        LOGI("Dropping event because there is no focused window or focused application.");
+        injectionResult = INPUT_EVENT_INJECTION_FAILED;
+        goto Failed;
+    }
+
+    // Check permissions.
+    if (! checkInjectionPermission(mFocusedWindow, entry->injectionState)) {
+        injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+        goto Failed;
+    }
+
+    // If the currently focused window is paused then keep waiting.
+    if (mFocusedWindow->paused) {
+#if DEBUG_FOCUS
+        LOGD("Waiting because focused window is paused.");
+#endif
+        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                mFocusedApplication, mFocusedWindow, nextWakeupTime);
+        goto Unresponsive;
+    }
+
+    // If the currently focused window is still working on previous events then keep waiting.
+    if (! isWindowFinishedWithPreviousInputLocked(mFocusedWindow)) {
+#if DEBUG_FOCUS
+        LOGD("Waiting because focused window still processing previous input.");
+#endif
+        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                mFocusedApplication, mFocusedWindow, nextWakeupTime);
+        goto Unresponsive;
+    }
+
+    // Success!  Output targets.
+    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+    addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND, BitSet32(0));
+
+    // Done.
+Failed:
+Unresponsive:
+    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
+    updateDispatchStatisticsLocked(currentTime, entry,
+            injectionResult, timeSpentWaitingForApplication);
+#if DEBUG_FOCUS
+    LOGD("findFocusedWindow finished: injectionResult=%d, "
+            "timeSpendWaitingForApplication=%0.1fms",
+            injectionResult, timeSpentWaitingForApplication / 1000000.0);
+#endif
+    return injectionResult;
+}
+
+int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
+        const MotionEntry* entry, nsecs_t* nextWakeupTime) {
+    enum InjectionPermission {
+        INJECTION_PERMISSION_UNKNOWN,
+        INJECTION_PERMISSION_GRANTED,
+        INJECTION_PERMISSION_DENIED
+    };
+
+    mCurrentInputTargets.clear();
+
+    nsecs_t startTime = now();
+
+    // For security reasons, we defer updating the touch state until we are sure that
+    // event injection will be allowed.
+    //
+    // FIXME In the original code, screenWasOff could never be set to true.
+    //       The reason is that the POLICY_FLAG_WOKE_HERE
+    //       and POLICY_FLAG_BRIGHT_HERE flags were set only when preprocessing raw
+    //       EV_KEY, EV_REL and EV_ABS events.  As it happens, the touch event was
+    //       actually enqueued using the policyFlags that appeared in the final EV_SYN
+    //       events upon which no preprocessing took place.  So policyFlags was always 0.
+    //       In the new native input dispatcher we're a bit more careful about event
+    //       preprocessing so the touches we receive can actually have non-zero policyFlags.
+    //       Unfortunately we obtain undesirable behavior.
+    //
+    //       Here's what happens:
+    //
+    //       When the device dims in anticipation of going to sleep, touches
+    //       in windows which have FLAG_TOUCHABLE_WHEN_WAKING cause
+    //       the device to brighten and reset the user activity timer.
+    //       Touches on other windows (such as the launcher window)
+    //       are dropped.  Then after a moment, the device goes to sleep.  Oops.
+    //
+    //       Also notice how screenWasOff was being initialized using POLICY_FLAG_BRIGHT_HERE
+    //       instead of POLICY_FLAG_WOKE_HERE...
+    //
+    bool screenWasOff = false; // original policy: policyFlags & POLICY_FLAG_BRIGHT_HERE;
+
+    int32_t action = entry->action;
+    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
+
+    // Update the touch state as needed based on the properties of the touch event.
+    int32_t injectionResult = INPUT_EVENT_INJECTION_PENDING;
+    InjectionPermission injectionPermission = INJECTION_PERMISSION_UNKNOWN;
+    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+        mTempTouchState.reset();
+        mTempTouchState.down = true;
+    } else {
+        mTempTouchState.copyFrom(mTouchState);
+    }
+
+    bool isSplit = mTempTouchState.split && mTempTouchState.down;
+    if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+            || (isSplit && maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN)) {
+        /* Case 1: New splittable pointer going down. */
+
+        int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+        int32_t x = int32_t(entry->firstSample.pointerCoords[pointerIndex].x);
+        int32_t y = int32_t(entry->firstSample.pointerCoords[pointerIndex].y);
+        const InputWindow* newTouchedWindow = NULL;
+        const InputWindow* topErrorWindow = NULL;
+
+        // Traverse windows from front to back to find touched window and outside targets.
+        size_t numWindows = mWindows.size();
+        for (size_t i = 0; i < numWindows; i++) {
+            const InputWindow* window = & mWindows.editItemAt(i);
+            int32_t flags = window->layoutParamsFlags;
+
+            if (flags & InputWindow::FLAG_SYSTEM_ERROR) {
+                if (! topErrorWindow) {
+                    topErrorWindow = window;
+                }
+            }
+
+            if (window->visible) {
+                if (! (flags & InputWindow::FLAG_NOT_TOUCHABLE)) {
+                    bool isTouchModal = (flags & (InputWindow::FLAG_NOT_FOCUSABLE
+                            | InputWindow::FLAG_NOT_TOUCH_MODAL)) == 0;
+                    if (isTouchModal || window->touchableAreaContainsPoint(x, y)) {
+                        if (! screenWasOff || flags & InputWindow::FLAG_TOUCHABLE_WHEN_WAKING) {
+                            newTouchedWindow = window;
+                        }
+                        break; // found touched window, exit window loop
+                    }
+                }
+
+                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
+                        && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
+                    int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
+                    if (isWindowObscuredAtPointLocked(window, x, y)) {
+                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+                    }
+
+                    mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
+                }
+            }
+        }
+
+        // If there is an error window but it is not taking focus (typically because
+        // it is invisible) then wait for it.  Any other focused window may in
+        // fact be in ANR state.
+        if (topErrorWindow && newTouchedWindow != topErrorWindow) {
+#if DEBUG_FOCUS
+            LOGD("Waiting because system error window is pending.");
+#endif
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    NULL, NULL, nextWakeupTime);
+            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
+            goto Unresponsive;
+        }
+
+        // Figure out whether splitting will be allowed for this window.
+        if (newTouchedWindow
+                && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
+            // New window supports splitting.
+            isSplit = true;
+        } else if (isSplit) {
+            // New window does not support splitting but we have already split events.
+            // Assign the pointer to the first foreground window we find.
+            // (May be NULL which is why we put this code block before the next check.)
+            newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
+        }
+
+        // If we did not find a touched window then fail.
+        if (! newTouchedWindow) {
+            if (mFocusedApplication) {
+#if DEBUG_FOCUS
+                LOGD("Waiting because there is no touched window but there is a "
+                        "focused application that may eventually add a new window: %s.",
+                        getApplicationWindowLabelLocked(mFocusedApplication, NULL).string());
+#endif
+                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                        mFocusedApplication, NULL, nextWakeupTime);
+                goto Unresponsive;
+            }
+
+            LOGI("Dropping event because there is no touched window or focused application.");
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            goto Failed;
+        }
+
+        // Set target flags.
+        int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
+        if (isSplit) {
+            targetFlags |= InputTarget::FLAG_SPLIT;
+        }
+        if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
+            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+        }
+
+        // Update the temporary touch state.
+        BitSet32 pointerIds;
+        if (isSplit) {
+            uint32_t pointerId = entry->pointerIds[pointerIndex];
+            pointerIds.markBit(pointerId);
+        }
+        mTempTouchState.addOrUpdateWindow(newTouchedWindow, targetFlags, pointerIds);
+    } else {
+        /* Case 2: Pointer move, up, cancel or non-splittable pointer down. */
+
+        // If the pointer is not currently down, then ignore the event.
+        if (! mTempTouchState.down) {
+            LOGI("Dropping event because the pointer is not down.");
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            goto Failed;
+        }
+    }
+
+    // Check permission to inject into all touched foreground windows and ensure there
+    // is at least one touched foreground window.
+    {
+        bool haveForegroundWindow = false;
+        for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
+            const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+            if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
+                haveForegroundWindow = true;
+                if (! checkInjectionPermission(touchedWindow.window, entry->injectionState)) {
+                    injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+                    injectionPermission = INJECTION_PERMISSION_DENIED;
+                    goto Failed;
+                }
+            }
+        }
+        if (! haveForegroundWindow) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+            LOGD("Dropping event because there is no touched foreground window to receive it.");
+#endif
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            goto Failed;
+        }
+
+        // Permission granted to injection into all touched foreground windows.
+        injectionPermission = INJECTION_PERMISSION_GRANTED;
+    }
+
+    // Ensure all touched foreground windows are ready for new input.
+    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
+        const TouchedWindow& touchedWindow = mTempTouchState.windows[i];
+        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
+            // If the touched window is paused then keep waiting.
+            if (touchedWindow.window->paused) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+                LOGD("Waiting because touched window is paused.");
+#endif
+                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                        NULL, touchedWindow.window, nextWakeupTime);
+                goto Unresponsive;
+            }
+
+            // If the touched window is still working on previous events then keep waiting.
+            if (! isWindowFinishedWithPreviousInputLocked(touchedWindow.window)) {
+#if DEBUG_FOCUS
+                LOGD("Waiting because touched window still processing previous input.");
+#endif
+                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                        NULL, touchedWindow.window, nextWakeupTime);
+                goto Unresponsive;
+            }
+        }
+    }
+
+    // If this is the first pointer going down and the touched window has a wallpaper
+    // then also add the touched wallpaper windows so they are locked in for the duration
+    // of the touch gesture.
+    if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+        const InputWindow* foregroundWindow = mTempTouchState.getFirstForegroundWindow();
+        if (foregroundWindow->hasWallpaper) {
+            for (size_t i = 0; i < mWindows.size(); i++) {
+                const InputWindow* window = & mWindows[i];
+                if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
+                    mTempTouchState.addOrUpdateWindow(window,
+                            InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
+                }
+            }
+        }
+    }
+
+    // Success!  Output targets.
+    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+
+    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
+        const TouchedWindow& touchedWindow = mTempTouchState.windows.itemAt(i);
+        addWindowTargetLocked(touchedWindow.window, touchedWindow.targetFlags,
+                touchedWindow.pointerIds);
+    }
+
+    // Drop the outside touch window since we will not care about them in the next iteration.
+    mTempTouchState.removeOutsideTouchWindows();
+
+Failed:
+    // Check injection permission once and for all.
+    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
+        if (checkInjectionPermission(NULL, entry->injectionState)) {
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+        } else {
+            injectionPermission = INJECTION_PERMISSION_DENIED;
+        }
+    }
+
+    // Update final pieces of touch state if the injector had permission.
+    if (injectionPermission == INJECTION_PERMISSION_GRANTED) {
+        if (maskedAction == AMOTION_EVENT_ACTION_UP
+                || maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
+            // All pointers up or canceled.
+            mTempTouchState.reset();
+        } else if (maskedAction == AMOTION_EVENT_ACTION_DOWN) {
+            // First pointer went down.
+            if (mTouchState.down) {
+#if DEBUG_FOCUS
+                LOGD("Pointer down received while already down.");
+#endif
+            }
+        } else if (maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
+            // One pointer went up.
+            if (isSplit) {
+                int32_t pointerIndex = getMotionEventActionPointerIndex(action);
+                uint32_t pointerId = entry->pointerIds[pointerIndex];
+
+                for (size_t i = 0; i < mTempTouchState.windows.size(); ) {
+                    TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
+                    if (touchedWindow.targetFlags & InputTarget::FLAG_SPLIT) {
+                        touchedWindow.pointerIds.clearBit(pointerId);
+                        if (touchedWindow.pointerIds.isEmpty()) {
+                            mTempTouchState.windows.removeAt(i);
+                            continue;
+                        }
+                    }
+                    i += 1;
+                }
+            }
+        }
+
+        // Save changes to touch state.
+        mTouchState.copyFrom(mTempTouchState);
+    } else {
+#if DEBUG_FOCUS
+        LOGD("Not updating touch focus because injection was denied.");
+#endif
+    }
+
+Unresponsive:
+    // Reset temporary touch state to ensure we release unnecessary references to input channels.
+    mTempTouchState.reset();
+
+    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
+    updateDispatchStatisticsLocked(currentTime, entry,
+            injectionResult, timeSpentWaitingForApplication);
+#if DEBUG_FOCUS
+    LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d, "
+            "timeSpentWaitingForApplication=%0.1fms",
+            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
+#endif
+    return injectionResult;
+}
+
+void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags,
+        BitSet32 pointerIds) {
+    mCurrentInputTargets.push();
+
+    InputTarget& target = mCurrentInputTargets.editTop();
+    target.inputChannel = window->inputChannel;
+    target.flags = targetFlags;
+    target.xOffset = - window->frameLeft;
+    target.yOffset = - window->frameTop;
+    target.pointerIds = pointerIds;
+}
+
+void InputDispatcher::addMonitoringTargetsLocked() {
+    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+        mCurrentInputTargets.push();
+
+        InputTarget& target = mCurrentInputTargets.editTop();
+        target.inputChannel = mMonitoringChannels[i];
+        target.flags = 0;
+        target.xOffset = 0;
+        target.yOffset = 0;
+    }
+}
+
+bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
+        const InjectionState* injectionState) {
+    if (injectionState
+            && (window == NULL || window->ownerUid != injectionState->injectorUid)
+            && !hasInjectionPermission(injectionState->injectorPid, injectionState->injectorUid)) {
+        if (window) {
+            LOGW("Permission denied: injecting event from pid %d uid %d to window "
+                    "with input channel %s owned by uid %d",
+                    injectionState->injectorPid, injectionState->injectorUid,
+                    window->inputChannel->getName().string(),
+                    window->ownerUid);
+        } else {
+            LOGW("Permission denied: injecting event from pid %d uid %d",
+                    injectionState->injectorPid, injectionState->injectorUid);
+        }
+        return false;
+    }
+    return true;
+}
+
+bool InputDispatcher::isWindowObscuredAtPointLocked(
+        const InputWindow* window, int32_t x, int32_t y) const {
+    size_t numWindows = mWindows.size();
+    for (size_t i = 0; i < numWindows; i++) {
+        const InputWindow* other = & mWindows.itemAt(i);
+        if (other == window) {
+            break;
+        }
+        if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool InputDispatcher::isWindowFinishedWithPreviousInputLocked(const InputWindow* window) {
+    ssize_t connectionIndex = getConnectionIndexLocked(window->inputChannel);
+    if (connectionIndex >= 0) {
+        sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+        return connection->outboundQueue.isEmpty();
+    } else {
+        return true;
+    }
+}
+
+String8 InputDispatcher::getApplicationWindowLabelLocked(const InputApplication* application,
+        const InputWindow* window) {
+    if (application) {
+        if (window) {
+            String8 label(application->name);
+            label.append(" - ");
+            label.append(window->name);
+            return label;
+        } else {
+            return application->name;
+        }
+    } else if (window) {
+        return window->name;
+    } else {
+        return String8("<unknown application or window>");
+    }
+}
+
+void InputDispatcher::pokeUserActivityLocked(const EventEntry* eventEntry) {
+    int32_t eventType = POWER_MANAGER_BUTTON_EVENT;
+    if (eventEntry->type == EventEntry::TYPE_MOTION) {
+        const MotionEntry* motionEntry = static_cast<const MotionEntry*>(eventEntry);
+        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+            switch (motionEntry->action) {
+            case AMOTION_EVENT_ACTION_DOWN:
+                eventType = POWER_MANAGER_TOUCH_EVENT;
+                break;
+            case AMOTION_EVENT_ACTION_UP:
+                eventType = POWER_MANAGER_TOUCH_UP_EVENT;
+                break;
+            default:
+                if (motionEntry->eventTime - motionEntry->downTime < LONG_TOUCH_DELAY) {
+                    eventType = POWER_MANAGER_TOUCH_EVENT;
+                } else {
+                    eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
+                }
+                break;
+            }
+        }
+    }
+
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doPokeUserActivityLockedInterruptible);
+    commandEntry->eventTime = eventEntry->eventTime;
+    commandEntry->userActivityEventType = eventType;
+}
+
+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, "
+            "xOffset=%f, yOffset=%f, "
+            "windowType=%d, pointerIds=0x%x, "
+            "resumeWithAppendedMotionSample=%s",
+            connection->getInputChannelName(), inputTarget->flags,
+            inputTarget->xOffset, inputTarget->yOffset,
+            inputTarget->windowType, inputTarget->pointerIds.value,
+            toString(resumeWithAppendedMotionSample));
+#endif
+
+    // Make sure we are never called for streaming when splitting across multiple windows.
+    bool isSplit = inputTarget->flags & InputTarget::FLAG_SPLIT;
+    assert(! (resumeWithAppendedMotionSample && isSplit));
+
+    // Skip this event if the connection status is not normal.
+    // We don't want to enqueue additional outbound events if the connection is broken.
+    if (connection->status != Connection::STATUS_NORMAL) {
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Dropping event because the channel status is %s",
+                connection->getInputChannelName(), connection->getStatusLabel());
+#endif
+        return;
+    }
+
+    // Split a motion event if needed.
+    if (isSplit) {
+        assert(eventEntry->type == EventEntry::TYPE_MOTION);
+
+        MotionEntry* originalMotionEntry = static_cast<MotionEntry*>(eventEntry);
+        if (inputTarget->pointerIds.count() != originalMotionEntry->pointerCount) {
+            MotionEntry* splitMotionEntry = splitMotionEvent(
+                    originalMotionEntry, inputTarget->pointerIds);
+#if DEBUG_FOCUS
+            LOGD("channel '%s' ~ Split motion event.",
+                    connection->getInputChannelName());
+            logOutboundMotionDetailsLocked("  ", splitMotionEntry);
+#endif
+            eventEntry = splitMotionEntry;
+        }
+    }
+
+    // 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).
+            MotionEntry* motionEntry = static_cast<MotionEntry*>(eventEntry);
+            MotionSample* appendedMotionSample = motionEntry->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
+            inputTarget->flags, inputTarget->xOffset, inputTarget->yOffset);
+    if (dispatchEntry->hasForegroundTarget()) {
+        incrementPendingForegroundDispatchesLocked(eventEntry);
+    }
+
+    // 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.headSentinel.next;
+    assert(! dispatchEntry->inProgress);
+
+    // Mark the dispatch entry as in progress.
+    dispatchEntry->inProgress = true;
+
+    // Update the connection's input state.
+    EventEntry* eventEntry = dispatchEntry->eventEntry;
+    InputState::Consistency consistency = connection->inputState.trackEvent(eventEntry);
+
+#if FILTER_INPUT_EVENTS
+    // Filter out inconsistent sequences of input events.
+    // The input system may drop or inject events in a way that could violate implicit
+    // invariants on input state and potentially cause an application to crash
+    // or think that a key or pointer is stuck down.  Technically we make no guarantees
+    // of consistency but it would be nice to improve on this where possible.
+    // XXX: This code is a proof of concept only.  Not ready for prime time.
+    if (consistency == InputState::TOLERABLE) {
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("channel '%s' ~ Sending an event that is inconsistent with the connection's "
+                "current input state but that is likely to be tolerated by the application.",
+                connection->getInputChannelName());
+#endif
+    } else if (consistency == InputState::BROKEN) {
+        LOGI("channel '%s' ~ Dropping an event that is inconsistent with the connection's "
+                "current input state and that is likely to cause the application to crash.",
+                connection->getInputChannelName());
+        startNextDispatchCycleLocked(currentTime, connection);
+        return;
+    }
+#endif
+
+    // Publish the event.
+    status_t status;
+    switch (eventEntry->type) {
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* keyEntry = static_cast<KeyEntry*>(eventEntry);
+
+        // Apply target flags.
+        int32_t action = keyEntry->action;
+        int32_t flags = keyEntry->flags;
+
+        // 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);
+            abortBrokenDispatchCycleLocked(currentTime, connection);
+            return;
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(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_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);
+            abortBrokenDispatchCycleLocked(currentTime, connection);
+            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);
+                abortBrokenDispatchCycleLocked(currentTime, connection);
+                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);
+        abortBrokenDispatchCycleLocked(currentTime, connection);
+        return;
+    }
+
+    // Record information about the newly started dispatch cycle.
+    connection->lastEventTime = eventEntry->eventTime;
+    connection->lastDispatchTime = currentTime;
+
+    // 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;
+    }
+
+    // Notify other system components.
+    onDispatchCycleFinishedLocked(currentTime, connection);
+
+    // 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);
+        abortBrokenDispatchCycleLocked(currentTime, connection);
+        return;
+    }
+
+    startNextDispatchCycleLocked(currentTime, connection);
+}
+
+void InputDispatcher::startNextDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+    // Start the next dispatch cycle for this connection.
+    while (! connection->outboundQueue.isEmpty()) {
+        DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.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->hasForegroundTarget()) {
+                decrementPendingForegroundDispatchesLocked(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.
+            // 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::abortBrokenDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ abortBrokenDispatchCycle - broken=%s",
+            connection->getInputChannelName(), toString(broken));
+#endif
+
+    // Clear the outbound queue.
+    drainOutboundQueueLocked(connection.get());
+
+    // The connection appears to be unrecoverably broken.
+    // Ignore already broken or zombie connections.
+    if (connection->status == Connection::STATUS_NORMAL) {
+        connection->status = Connection::STATUS_BROKEN;
+
+        // Notify other system components.
+        onDispatchCycleBrokenLocked(currentTime, connection);
+    }
+}
+
+void InputDispatcher::drainOutboundQueueLocked(Connection* connection) {
+    while (! connection->outboundQueue.isEmpty()) {
+        DispatchEntry* dispatchEntry = connection->outboundQueue.dequeueAtHead();
+        if (dispatchEntry->hasForegroundTarget()) {
+            decrementPendingForegroundDispatchesLocked(dispatchEntry->eventEntry);
+        }
+        mAllocator.releaseDispatchEntry(dispatchEntry);
+    }
+
+    deactivateConnectionLocked(connection);
+}
+
+int 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 0; // remove the callback
+        }
+
+        nsecs_t currentTime = now();
+
+        sp<Connection> connection = d->mConnectionsByReceiveFd.valueAt(connectionIndex);
+        if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
+            LOGE("channel '%s' ~ Consumer closed input channel or an error occurred.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            d->abortBrokenDispatchCycleLocked(currentTime, connection);
+            d->runCommandsLockedInterruptible();
+            return 0; // remove the callback
+        }
+
+        if (! (events & ALOOPER_EVENT_INPUT)) {
+            LOGW("channel '%s' ~ Received spurious callback for unhandled poll event.  "
+                    "events=0x%x", connection->getInputChannelName(), events);
+            return 1;
+        }
+
+        status_t status = connection->inputPublisher.receiveFinishedSignal();
+        if (status) {
+            LOGE("channel '%s' ~ Failed to receive finished signal.  status=%d",
+                    connection->getInputChannelName(), status);
+            d->abortBrokenDispatchCycleLocked(currentTime, connection);
+            d->runCommandsLockedInterruptible();
+            return 0; // remove the callback
+        }
+
+        d->finishDispatchCycleLocked(currentTime, connection);
+        d->runCommandsLockedInterruptible();
+        return 1;
+    } // release lock
+}
+
+void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(
+        InputState::CancelationOptions options, const char* reason) {
+    for (size_t i = 0; i < mConnectionsByReceiveFd.size(); i++) {
+        synthesizeCancelationEventsForConnectionLocked(
+                mConnectionsByReceiveFd.valueAt(i), options, reason);
+    }
+}
+
+void InputDispatcher::synthesizeCancelationEventsForInputChannelLocked(
+        const sp<InputChannel>& channel, InputState::CancelationOptions options,
+        const char* reason) {
+    ssize_t index = getConnectionIndexLocked(channel);
+    if (index >= 0) {
+        synthesizeCancelationEventsForConnectionLocked(
+                mConnectionsByReceiveFd.valueAt(index), options, reason);
+    }
+}
+
+void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
+        const sp<Connection>& connection, InputState::CancelationOptions options,
+        const char* reason) {
+    nsecs_t currentTime = now();
+
+    mTempCancelationEvents.clear();
+    connection->inputState.synthesizeCancelationEvents(currentTime, & mAllocator,
+            mTempCancelationEvents, options);
+
+    if (! mTempCancelationEvents.isEmpty()
+            && connection->status != Connection::STATUS_BROKEN) {
+#if DEBUG_OUTBOUND_EVENT_DETAILS
+        LOGD("channel '%s' ~ Synthesized %d cancelation events to bring channel back in sync "
+                "with reality: %s, options=%d.",
+                connection->getInputChannelName(), mTempCancelationEvents.size(), reason, options);
+#endif
+        for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
+            EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
+            switch (cancelationEventEntry->type) {
+            case EventEntry::TYPE_KEY:
+                logOutboundKeyDetailsLocked("cancel - ",
+                        static_cast<KeyEntry*>(cancelationEventEntry));
+                break;
+            case EventEntry::TYPE_MOTION:
+                logOutboundMotionDetailsLocked("cancel - ",
+                        static_cast<MotionEntry*>(cancelationEventEntry));
+                break;
+            }
+
+            int32_t xOffset, yOffset;
+            const InputWindow* window = getWindowLocked(connection->inputChannel);
+            if (window) {
+                xOffset = -window->frameLeft;
+                yOffset = -window->frameTop;
+            } else {
+                xOffset = 0;
+                yOffset = 0;
+            }
+
+            DispatchEntry* cancelationDispatchEntry =
+                    mAllocator.obtainDispatchEntry(cancelationEventEntry, // increments ref
+                    0, xOffset, yOffset);
+            connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
+
+            mAllocator.releaseEventEntry(cancelationEventEntry);
+        }
+
+        if (!connection->outboundQueue.headSentinel.next->inProgress) {
+            startDispatchCycleLocked(currentTime, connection);
+        }
+    }
+}
+
+InputDispatcher::MotionEntry*
+InputDispatcher::splitMotionEvent(const MotionEntry* originalMotionEntry, BitSet32 pointerIds) {
+    assert(pointerIds.value != 0);
+
+    uint32_t splitPointerIndexMap[MAX_POINTERS];
+    int32_t splitPointerIds[MAX_POINTERS];
+    PointerCoords splitPointerCoords[MAX_POINTERS];
+
+    uint32_t originalPointerCount = originalMotionEntry->pointerCount;
+    uint32_t splitPointerCount = 0;
+
+    for (uint32_t originalPointerIndex = 0; originalPointerIndex < originalPointerCount;
+            originalPointerIndex++) {
+        int32_t pointerId = uint32_t(originalMotionEntry->pointerIds[originalPointerIndex]);
+        if (pointerIds.hasBit(pointerId)) {
+            splitPointerIndexMap[splitPointerCount] = originalPointerIndex;
+            splitPointerIds[splitPointerCount] = pointerId;
+            splitPointerCoords[splitPointerCount] =
+                    originalMotionEntry->firstSample.pointerCoords[originalPointerIndex];
+            splitPointerCount += 1;
+        }
+    }
+    assert(splitPointerCount == pointerIds.count());
+
+    int32_t action = originalMotionEntry->action;
+    int32_t maskedAction = action & AMOTION_EVENT_ACTION_MASK;
+    if (maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
+            || maskedAction == AMOTION_EVENT_ACTION_POINTER_UP) {
+        int32_t originalPointerIndex = getMotionEventActionPointerIndex(action);
+        int32_t pointerId = originalMotionEntry->pointerIds[originalPointerIndex];
+        if (pointerIds.hasBit(pointerId)) {
+            if (pointerIds.count() == 1) {
+                // The first/last pointer went down/up.
+                action = maskedAction == AMOTION_EVENT_ACTION_POINTER_DOWN
+                        ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+            } else {
+                // A secondary pointer went down/up.
+                uint32_t splitPointerIndex = 0;
+                while (pointerId != splitPointerIds[splitPointerIndex]) {
+                    splitPointerIndex += 1;
+                }
+                action = maskedAction | (splitPointerIndex
+                        << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
+            }
+        } else {
+            // An unrelated pointer changed.
+            action = AMOTION_EVENT_ACTION_MOVE;
+        }
+    }
+
+    MotionEntry* splitMotionEntry = mAllocator.obtainMotionEntry(
+            originalMotionEntry->eventTime,
+            originalMotionEntry->deviceId,
+            originalMotionEntry->source,
+            originalMotionEntry->policyFlags,
+            action,
+            originalMotionEntry->flags,
+            originalMotionEntry->metaState,
+            originalMotionEntry->edgeFlags,
+            originalMotionEntry->xPrecision,
+            originalMotionEntry->yPrecision,
+            originalMotionEntry->downTime,
+            splitPointerCount, splitPointerIds, splitPointerCoords);
+
+    for (MotionSample* originalMotionSample = originalMotionEntry->firstSample.next;
+            originalMotionSample != NULL; originalMotionSample = originalMotionSample->next) {
+        for (uint32_t splitPointerIndex = 0; splitPointerIndex < splitPointerCount;
+                splitPointerIndex++) {
+            uint32_t originalPointerIndex = splitPointerIndexMap[splitPointerIndex];
+            splitPointerCoords[splitPointerIndex] =
+                    originalMotionSample->pointerCoords[originalPointerIndex];
+        }
+
+        mAllocator.appendMotionSample(splitMotionEntry, originalMotionSample->eventTime,
+                splitPointerCoords);
+    }
+
+    return splitMotionEntry;
+}
+
+void InputDispatcher::notifyConfigurationChanged(nsecs_t eventTime) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifyConfigurationChanged - eventTime=%lld", eventTime);
+#endif
+
+    bool needWake;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        ConfigurationChangedEntry* newEntry = mAllocator.obtainConfigurationChangedEntry(eventTime);
+        needWake = enqueueInboundEventLocked(newEntry);
+    } // release lock
+
+    if (needWake) {
+        mLooper->wake();
+    }
+}
+
+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
+    if (! validateKeyEvent(action)) {
+        return;
+    }
+
+    policyFlags |= POLICY_FLAG_TRUSTED;
+    mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
+            keyCode, scanCode, /*byref*/ policyFlags);
+
+    bool needWake;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        int32_t repeatCount = 0;
+        KeyEntry* newEntry = mAllocator.obtainKeyEntry(eventTime,
+                deviceId, source, policyFlags, action, flags, keyCode, scanCode,
+                metaState, repeatCount, downTime);
+
+        needWake = enqueueInboundEventLocked(newEntry);
+    } // release lock
+
+    if (needWake) {
+        mLooper->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
+    if (! validateMotionEvent(action, pointerCount, pointerIds)) {
+        return;
+    }
+
+    policyFlags |= POLICY_FLAG_TRUSTED;
+    mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
+
+    bool needWake;
+    { // 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.tailSentinel.prev;
+                    entry != & mInboundQueue.headSentinel; 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
+                return; // done!
+            }
+
+            // STREAMING CASE
+            //
+            // There is no pending motion event (of any kind) for this device in the inbound queue.
+            // Search the outbound queue for the current foreground targets to find a dispatched
+            // motion event that is still in progress.  If found, then, appen the new sample to
+            // that event and push it out to all current targets.  The logic in
+            // prepareDispatchCycleLocked takes care of the case where some targets may
+            // already have consumed the motion event by starting a new dispatch cycle if needed.
+            if (mCurrentInputTargetsValid) {
+                for (size_t i = 0; i < mCurrentInputTargets.size(); i++) {
+                    const InputTarget& inputTarget = mCurrentInputTargets[i];
+                    if ((inputTarget.flags & InputTarget::FLAG_FOREGROUND) == 0) {
+                        // Skip non-foreground targets.  We only want to stream if there is at
+                        // least one foreground target whose dispatch is still in progress.
+                        continue;
+                    }
+
+                    ssize_t connectionIndex = getConnectionIndexLocked(inputTarget.inputChannel);
+                    if (connectionIndex < 0) {
+                        // Connection must no longer be valid.
+                        continue;
+                    }
+
+                    sp<Connection> connection = mConnectionsByReceiveFd.valueAt(connectionIndex);
+                    if (connection->outboundQueue.isEmpty()) {
+                        // This foreground target has an empty outbound queue.
+                        continue;
+                    }
+
+                    DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+                    if (! dispatchEntry->inProgress
+                            || dispatchEntry->eventEntry->type != EventEntry::TYPE_MOTION
+                            || dispatchEntry->isSplit()) {
+                        // No motion event is being dispatched, or it is being split across
+                        // windows in which case we cannot stream.
+                        continue;
+                    }
+
+                    MotionEntry* motionEntry = static_cast<MotionEntry*>(
+                            dispatchEntry->eventEntry);
+                    if (motionEntry->action != AMOTION_EVENT_ACTION_MOVE
+                            || motionEntry->deviceId != deviceId
+                            || motionEntry->pointerCount != pointerCount
+                            || motionEntry->isInjected()) {
+                        // The motion event is not compatible with this move.
+                        continue;
+                    }
+
+                    // Hurray!  This foreground target is currently dispatching a move event
+                    // that we can stream onto.  Append the motion sample and resume dispatch.
+                    mAllocator.appendMotionSample(motionEntry, eventTime, pointerCoords);
+#if DEBUG_BATCHING
+                    LOGD("Appended motion sample onto batch for most recently dispatched "
+                            "motion event for this device in the outbound queues.  "
+                            "Attempting to stream the motion sample.");
+#endif
+                    nsecs_t currentTime = now();
+                    dispatchEventToCurrentInputTargetsLocked(currentTime, motionEntry,
+                            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);
+
+        needWake = enqueueInboundEventLocked(newEntry);
+    } // release lock
+
+    if (needWake) {
+        mLooper->wake();
+    }
+}
+
+void InputDispatcher::notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+        uint32_t policyFlags) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("notifySwitch - switchCode=%d, switchValue=%d, policyFlags=0x%x",
+            switchCode, switchValue, policyFlags);
+#endif
+
+    policyFlags |= POLICY_FLAG_TRUSTED;
+    mPolicy->notifySwitch(when, switchCode, switchValue, policyFlags);
+}
+
+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);
+
+    uint32_t policyFlags = POLICY_FLAG_INJECTED;
+    if (hasInjectionPermission(injectorPid, injectorUid)) {
+        policyFlags |= POLICY_FLAG_TRUSTED;
+    }
+
+    EventEntry* injectedEntry;
+    switch (event->getType()) {
+    case AINPUT_EVENT_TYPE_KEY: {
+        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
+        int32_t action = keyEvent->getAction();
+        if (! validateKeyEvent(action)) {
+            return INPUT_EVENT_INJECTION_FAILED;
+        }
+
+        nsecs_t eventTime = keyEvent->getEventTime();
+        int32_t deviceId = keyEvent->getDeviceId();
+        int32_t flags = keyEvent->getFlags();
+        int32_t keyCode = keyEvent->getKeyCode();
+        int32_t scanCode = keyEvent->getScanCode();
+        mPolicy->interceptKeyBeforeQueueing(eventTime, deviceId, action, /*byref*/ flags,
+                keyCode, scanCode, /*byref*/ policyFlags);
+
+        mLock.lock();
+        injectedEntry = mAllocator.obtainKeyEntry(eventTime, deviceId, keyEvent->getSource(),
+                policyFlags, action, flags, keyCode, scanCode, keyEvent->getMetaState(),
+                keyEvent->getRepeatCount(), keyEvent->getDownTime());
+        break;
+    }
+
+    case AINPUT_EVENT_TYPE_MOTION: {
+        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+        int32_t action = motionEvent->getAction();
+        size_t pointerCount = motionEvent->getPointerCount();
+        const int32_t* pointerIds = motionEvent->getPointerIds();
+        if (! validateMotionEvent(action, pointerCount, pointerIds)) {
+            return INPUT_EVENT_INJECTION_FAILED;
+        }
+
+        nsecs_t eventTime = motionEvent->getEventTime();
+        mPolicy->interceptGenericBeforeQueueing(eventTime, /*byref*/ policyFlags);
+
+        mLock.lock();
+        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
+        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
+        MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
+                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                action, motionEvent->getFlags(),
+                motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
+                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
+                motionEvent->getDownTime(), uint32_t(pointerCount),
+                pointerIds, samplePointerCoords);
+        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
+            sampleEventTimes += 1;
+            samplePointerCoords += pointerCount;
+            mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
+        }
+        injectedEntry = motionEntry;
+        break;
+    }
+
+    default:
+        LOGW("Cannot inject event of type %d", event->getType());
+        return INPUT_EVENT_INJECTION_FAILED;
+    }
+
+    InjectionState* injectionState = mAllocator.obtainInjectionState(injectorPid, injectorUid);
+    if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+        injectionState->injectionIsAsync = true;
+    }
+
+    injectionState->refCount += 1;
+    injectedEntry->injectionState = injectionState;
+
+    bool needWake = enqueueInboundEventLocked(injectedEntry);
+    mLock.unlock();
+
+    if (needWake) {
+        mLooper->wake();
+    }
+
+    int32_t injectionResult;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+            injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+        } else {
+            for (;;) {
+                injectionResult = injectionState->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 (injectionState->pendingForegroundDispatches != 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
+                            injectionState->pendingForegroundDispatches);
+#endif
+                    nsecs_t remainingTimeout = endTime - now();
+                    if (remainingTimeout <= 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Timed out waiting for pending foreground "
+                            "dispatches to finish.");
+#endif
+                        injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+                        break;
+                    }
+
+                    mInjectionSyncFinishedCondition.waitRelative(mLock, remainingTimeout);
+                }
+            }
+        }
+
+        mAllocator.releaseInjectionState(injectionState);
+    } // release lock
+
+#if DEBUG_INJECTION
+    LOGD("injectInputEvent - Finished with result %d.  "
+            "injectorPid=%d, injectorUid=%d",
+            injectionResult, injectorPid, injectorUid);
+#endif
+
+    return injectionResult;
+}
+
+bool InputDispatcher::hasInjectionPermission(int32_t injectorPid, int32_t injectorUid) {
+    return injectorUid == 0
+            || mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
+}
+
+void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
+    InjectionState* injectionState = entry->injectionState;
+    if (injectionState) {
+#if DEBUG_INJECTION
+        LOGD("Setting input event injection result to %d.  "
+                "injectorPid=%d, injectorUid=%d",
+                 injectionResult, injectionState->injectorPid, injectionState->injectorUid);
+#endif
+
+        if (injectionState->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;
+            }
+        }
+
+        injectionState->injectionResult = injectionResult;
+        mInjectionResultAvailableCondition.broadcast();
+    }
+}
+
+void InputDispatcher::incrementPendingForegroundDispatchesLocked(EventEntry* entry) {
+    InjectionState* injectionState = entry->injectionState;
+    if (injectionState) {
+        injectionState->pendingForegroundDispatches += 1;
+    }
+}
+
+void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
+    InjectionState* injectionState = entry->injectionState;
+    if (injectionState) {
+        injectionState->pendingForegroundDispatches -= 1;
+
+        if (injectionState->pendingForegroundDispatches == 0) {
+            mInjectionSyncFinishedCondition.broadcast();
+        }
+    }
+}
+
+const InputWindow* InputDispatcher::getWindowLocked(const sp<InputChannel>& inputChannel) {
+    for (size_t i = 0; i < mWindows.size(); i++) {
+        const InputWindow* window = & mWindows[i];
+        if (window->inputChannel == inputChannel) {
+            return window;
+        }
+    }
+    return NULL;
+}
+
+void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
+#if DEBUG_FOCUS
+    LOGD("setInputWindows");
+#endif
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Clear old window pointers.
+        sp<InputChannel> oldFocusedWindowChannel;
+        if (mFocusedWindow) {
+            oldFocusedWindowChannel = mFocusedWindow->inputChannel;
+            mFocusedWindow = NULL;
+        }
+
+        mWindows.clear();
+
+        // Loop over new windows and rebuild the necessary window pointers for
+        // tracking focus and touch.
+        mWindows.appendVector(inputWindows);
+
+        size_t numWindows = mWindows.size();
+        for (size_t i = 0; i < numWindows; i++) {
+            const InputWindow* window = & mWindows.itemAt(i);
+            if (window->hasFocus) {
+                mFocusedWindow = window;
+                break;
+            }
+        }
+
+        if (oldFocusedWindowChannel != NULL) {
+            if (!mFocusedWindow || oldFocusedWindowChannel != mFocusedWindow->inputChannel) {
+#if DEBUG_FOCUS
+                LOGD("Focus left window: %s",
+                        oldFocusedWindowChannel->getName().string());
+#endif
+                synthesizeCancelationEventsForInputChannelLocked(oldFocusedWindowChannel,
+                        InputState::CANCEL_NON_POINTER_EVENTS, "focus left window");
+                oldFocusedWindowChannel.clear();
+            }
+        }
+        if (mFocusedWindow && oldFocusedWindowChannel == NULL) {
+#if DEBUG_FOCUS
+            LOGD("Focus entered window: %s",
+                    mFocusedWindow->inputChannel->getName().string());
+#endif
+        }
+
+        for (size_t i = 0; i < mTouchState.windows.size(); ) {
+            TouchedWindow& touchedWindow = mTouchState.windows.editItemAt(i);
+            const InputWindow* window = getWindowLocked(touchedWindow.channel);
+            if (window) {
+                touchedWindow.window = window;
+                i += 1;
+            } else {
+#if DEBUG_FOCUS
+                LOGD("Touched window was removed: %s", touchedWindow.channel->getName().string());
+#endif
+                synthesizeCancelationEventsForInputChannelLocked(touchedWindow.channel,
+                        InputState::CANCEL_POINTER_EVENTS, "touched window was removed");
+                mTouchState.windows.removeAt(i);
+            }
+        }
+
+#if DEBUG_FOCUS
+        //logDispatchStateLocked();
+#endif
+    } // release lock
+
+    // Wake up poll loop since it may need to make new input dispatching choices.
+    mLooper->wake();
+}
+
+void InputDispatcher::setFocusedApplication(const InputApplication* inputApplication) {
+#if DEBUG_FOCUS
+    LOGD("setFocusedApplication");
+#endif
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        releaseFocusedApplicationLocked();
+
+        if (inputApplication) {
+            mFocusedApplicationStorage = *inputApplication;
+            mFocusedApplication = & mFocusedApplicationStorage;
+        }
+
+#if DEBUG_FOCUS
+        //logDispatchStateLocked();
+#endif
+    } // release lock
+
+    // Wake up poll loop since it may need to make new input dispatching choices.
+    mLooper->wake();
+}
+
+void InputDispatcher::releaseFocusedApplicationLocked() {
+    if (mFocusedApplication) {
+        mFocusedApplication = NULL;
+        mFocusedApplicationStorage.handle.clear();
+    }
+}
+
+void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
+#if DEBUG_FOCUS
+    LOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
+#endif
+
+    bool changed;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mDispatchEnabled != enabled || mDispatchFrozen != frozen) {
+            if (mDispatchFrozen && !frozen) {
+                resetANRTimeoutsLocked();
+            }
+
+            if (mDispatchEnabled && !enabled) {
+                resetAndDropEverythingLocked("dispatcher is being disabled");
+            }
+
+            mDispatchEnabled = enabled;
+            mDispatchFrozen = frozen;
+            changed = true;
+        } else {
+            changed = false;
+        }
+
+#if DEBUG_FOCUS
+        //logDispatchStateLocked();
+#endif
+    } // release lock
+
+    if (changed) {
+        // Wake up poll loop since it may need to make new input dispatching choices.
+        mLooper->wake();
+    }
+}
+
+void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
+#if DEBUG_FOCUS
+    LOGD("Resetting and dropping all events (%s).", reason);
+#endif
+
+    synthesizeCancelationEventsForAllConnectionsLocked(InputState::CANCEL_ALL_EVENTS, reason);
+
+    resetKeyRepeatLocked();
+    releasePendingEventLocked();
+    drainInboundQueueLocked();
+    resetTargetsLocked();
+
+    mTouchState.reset();
+}
+
+void InputDispatcher::logDispatchStateLocked() {
+    String8 dump;
+    dumpDispatchStateLocked(dump);
+
+    char* text = dump.lockBuffer(dump.size());
+    char* start = text;
+    while (*start != '\0') {
+        char* end = strchr(start, '\n');
+        if (*end == '\n') {
+            *(end++) = '\0';
+        }
+        LOGD("%s", start);
+        start = end;
+    }
+}
+
+void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
+    dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled);
+    dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen);
+
+    if (mFocusedApplication) {
+        dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
+                mFocusedApplication->name.string(),
+                mFocusedApplication->dispatchingTimeout / 1000000.0);
+    } else {
+        dump.append(INDENT "FocusedApplication: <null>\n");
+    }
+    dump.appendFormat(INDENT "FocusedWindow: name='%s'\n",
+            mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
+
+    dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down));
+    dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split));
+    if (!mTouchState.windows.isEmpty()) {
+        dump.append(INDENT "TouchedWindows:\n");
+        for (size_t i = 0; i < mTouchState.windows.size(); i++) {
+            const TouchedWindow& touchedWindow = mTouchState.windows[i];
+            dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n",
+                    i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value,
+                    touchedWindow.targetFlags);
+        }
+    } else {
+        dump.append(INDENT "TouchedWindows: <none>\n");
+    }
+
+    if (!mWindows.isEmpty()) {
+        dump.append(INDENT "Windows:\n");
+        for (size_t i = 0; i < mWindows.size(); i++) {
+            const InputWindow& window = mWindows[i];
+            dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, "
+                    "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, "
+                    "frame=[%d,%d][%d,%d], "
+                    "visibleFrame=[%d,%d][%d,%d], "
+                    "touchableArea=[%d,%d][%d,%d], "
+                    "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
+                    i, window.name.string(),
+                    toString(window.paused),
+                    toString(window.hasFocus),
+                    toString(window.hasWallpaper),
+                    toString(window.visible),
+                    toString(window.canReceiveKeys),
+                    window.layoutParamsFlags, window.layoutParamsType,
+                    window.layer,
+                    window.frameLeft, window.frameTop,
+                    window.frameRight, window.frameBottom,
+                    window.visibleFrameLeft, window.visibleFrameTop,
+                    window.visibleFrameRight, window.visibleFrameBottom,
+                    window.touchableAreaLeft, window.touchableAreaTop,
+                    window.touchableAreaRight, window.touchableAreaBottom,
+                    window.ownerPid, window.ownerUid,
+                    window.dispatchingTimeout / 1000000.0);
+        }
+    } else {
+        dump.append(INDENT "Windows: <none>\n");
+    }
+
+    if (!mMonitoringChannels.isEmpty()) {
+        dump.append(INDENT "MonitoringChannels:\n");
+        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+            const sp<InputChannel>& channel = mMonitoringChannels[i];
+            dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string());
+        }
+    } else {
+        dump.append(INDENT "MonitoringChannels: <none>\n");
+    }
+
+    dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
+
+    if (!mActiveConnections.isEmpty()) {
+        dump.append(INDENT "ActiveConnections:\n");
+        for (size_t i = 0; i < mActiveConnections.size(); i++) {
+            const Connection* connection = mActiveConnections[i];
+            dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u"
+                    "inputState.isNeutral=%s\n",
+                    i, connection->getInputChannelName(), connection->getStatusLabel(),
+                    connection->outboundQueue.count(),
+                    toString(connection->inputState.isNeutral()));
+        }
+    } else {
+        dump.append(INDENT "ActiveConnections: <none>\n");
+    }
+
+    if (isAppSwitchPendingLocked()) {
+        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
+                (mAppSwitchDueTime - now()) / 1000000.0);
+    } else {
+        dump.append(INDENT "AppSwitch: not pending\n");
+    }
+}
+
+status_t InputDispatcher::registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
+#if DEBUG_REGISTRATION
+    LOGD("channel '%s' ~ registerInputChannel - monitor=%s", inputChannel->getName().string(),
+            toString(monitor));
+#endif
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (getConnectionIndexLocked(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);
+
+        if (monitor) {
+            mMonitoringChannels.push(inputChannel);
+        }
+
+        mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, 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 = getConnectionIndexLocked(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;
+
+        for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+            if (mMonitoringChannels[i] == inputChannel) {
+                mMonitoringChannels.removeAt(i);
+                break;
+            }
+        }
+
+        mLooper->removeFd(inputChannel->getReceivePipeFd());
+
+        nsecs_t currentTime = now();
+        abortBrokenDispatchCycleLocked(currentTime, connection);
+
+        runCommandsLockedInterruptible();
+    } // release lock
+
+    // Wake the poll loop because removing the connection may have changed the current
+    // synchronization state.
+    mLooper->wake();
+    return OK;
+}
+
+ssize_t InputDispatcher::getConnectionIndexLocked(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) {
+}
+
+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::onANRLocked(
+        nsecs_t currentTime, const InputApplication* application, const InputWindow* window,
+        nsecs_t eventTime, nsecs_t waitStartTime) {
+    LOGI("Application is not responding: %s.  "
+            "%01.1fms since event, %01.1fms since wait started",
+            getApplicationWindowLabelLocked(application, window).string(),
+            (currentTime - eventTime) / 1000000.0,
+            (currentTime - waitStartTime) / 1000000.0);
+
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doNotifyANRLockedInterruptible);
+    if (application) {
+        commandEntry->inputApplicationHandle = application->handle;
+    }
+    if (window) {
+        commandEntry->inputChannel = window->inputChannel;
+    }
+}
+
+void InputDispatcher::doNotifyConfigurationChangedInterruptible(
+        CommandEntry* commandEntry) {
+    mLock.unlock();
+
+    mPolicy->notifyConfigurationChanged(commandEntry->eventTime);
+
+    mLock.lock();
+}
+
+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::doNotifyANRLockedInterruptible(
+        CommandEntry* commandEntry) {
+    mLock.unlock();
+
+    nsecs_t newTimeout = mPolicy->notifyANR(
+            commandEntry->inputApplicationHandle, commandEntry->inputChannel);
+
+    mLock.lock();
+
+    resumeAfterTargetsNotReadyTimeoutLocked(newTimeout, commandEntry->inputChannel);
+}
+
+void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
+        CommandEntry* commandEntry) {
+    KeyEntry* entry = commandEntry->keyEntry;
+    mReusableKeyEvent.initialize(entry->deviceId, entry->source, entry->action, entry->flags,
+            entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
+            entry->downTime, entry->eventTime);
+
+    mLock.unlock();
+
+    bool consumed = mPolicy->interceptKeyBeforeDispatching(commandEntry->inputChannel,
+            & mReusableKeyEvent, entry->policyFlags);
+
+    mLock.lock();
+
+    entry->interceptKeyResult = consumed
+            ? KeyEntry::INTERCEPT_KEY_RESULT_SKIP
+            : KeyEntry::INTERCEPT_KEY_RESULT_CONTINUE;
+    mAllocator.releaseKeyEntry(entry);
+}
+
+void InputDispatcher::doPokeUserActivityLockedInterruptible(CommandEntry* commandEntry) {
+    mLock.unlock();
+
+    mPolicy->pokeUserActivity(commandEntry->eventTime, commandEntry->userActivityEventType);
+
+    mLock.lock();
+}
+
+void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const EventEntry* entry,
+        int32_t injectionResult, nsecs_t timeSpentWaitingForApplication) {
+    // TODO Write some statistics about how long we spend waiting.
+}
+
+void InputDispatcher::dump(String8& dump) {
+    dump.append("Input Dispatcher State:\n");
+    dumpDispatchStateLocked(dump);
+}
+
+
+// --- InputDispatcher::Queue ---
+
+template <typename T>
+uint32_t InputDispatcher::Queue<T>::count() const {
+    uint32_t result = 0;
+    for (const T* entry = headSentinel.next; entry != & tailSentinel; entry = entry->next) {
+        result += 1;
+    }
+    return result;
+}
+
+
+// --- InputDispatcher::Allocator ---
+
+InputDispatcher::Allocator::Allocator() {
+}
+
+InputDispatcher::InjectionState*
+InputDispatcher::Allocator::obtainInjectionState(int32_t injectorPid, int32_t injectorUid) {
+    InjectionState* injectionState = mInjectionStatePool.alloc();
+    injectionState->refCount = 1;
+    injectionState->injectorPid = injectorPid;
+    injectionState->injectorUid = injectorUid;
+    injectionState->injectionIsAsync = false;
+    injectionState->injectionResult = INPUT_EVENT_INJECTION_PENDING;
+    injectionState->pendingForegroundDispatches = 0;
+    return injectionState;
+}
+
+void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
+        nsecs_t eventTime, uint32_t policyFlags) {
+    entry->type = type;
+    entry->refCount = 1;
+    entry->dispatchInProgress = false;
+    entry->eventTime = eventTime;
+    entry->policyFlags = policyFlags;
+    entry->injectionState = NULL;
+}
+
+void InputDispatcher::Allocator::releaseEventEntryInjectionState(EventEntry* entry) {
+    if (entry->injectionState) {
+        releaseInjectionState(entry->injectionState);
+        entry->injectionState = NULL;
+    }
+}
+
+InputDispatcher::ConfigurationChangedEntry*
+InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
+    ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
+    initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime, 0);
+    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, policyFlags);
+
+    entry->deviceId = deviceId;
+    entry->source = source;
+    entry->action = action;
+    entry->flags = flags;
+    entry->keyCode = keyCode;
+    entry->scanCode = scanCode;
+    entry->metaState = metaState;
+    entry->repeatCount = repeatCount;
+    entry->downTime = downTime;
+    entry->syntheticRepeat = false;
+    entry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+    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, policyFlags);
+
+    entry->eventTime = eventTime;
+    entry->deviceId = deviceId;
+    entry->source = source;
+    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,
+        int32_t targetFlags, float xOffset, float yOffset) {
+    DispatchEntry* entry = mDispatchEntryPool.alloc();
+    entry->eventEntry = eventEntry;
+    eventEntry->refCount += 1;
+    entry->targetFlags = targetFlags;
+    entry->xOffset = xOffset;
+    entry->yOffset = yOffset;
+    entry->inProgress = false;
+    entry->headMotionSample = NULL;
+    entry->tailMotionSample = NULL;
+    return entry;
+}
+
+InputDispatcher::CommandEntry* InputDispatcher::Allocator::obtainCommandEntry(Command command) {
+    CommandEntry* entry = mCommandEntryPool.alloc();
+    entry->command = command;
+    return entry;
+}
+
+void InputDispatcher::Allocator::releaseInjectionState(InjectionState* injectionState) {
+    injectionState->refCount -= 1;
+    if (injectionState->refCount == 0) {
+        mInjectionStatePool.free(injectionState);
+    } else {
+        assert(injectionState->refCount > 0);
+    }
+}
+
+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) {
+        releaseEventEntryInjectionState(entry);
+        mConfigurationChangeEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        releaseEventEntryInjectionState(entry);
+        mKeyEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        releaseEventEntryInjectionState(entry);
+        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;
+}
+
+void InputDispatcher::Allocator::recycleKeyEntry(KeyEntry* keyEntry) {
+    releaseEventEntryInjectionState(keyEntry);
+
+    keyEntry->dispatchInProgress = false;
+    keyEntry->syntheticRepeat = false;
+    keyEntry->interceptKeyResult = KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN;
+}
+
+
+// --- 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::InputState ---
+
+InputDispatcher::InputState::InputState() {
+}
+
+InputDispatcher::InputState::~InputState() {
+}
+
+bool InputDispatcher::InputState::isNeutral() const {
+    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
+}
+
+InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackEvent(
+        const EventEntry* entry) {
+    switch (entry->type) {
+    case EventEntry::TYPE_KEY:
+        return trackKey(static_cast<const KeyEntry*>(entry));
+
+    case EventEntry::TYPE_MOTION:
+        return trackMotion(static_cast<const MotionEntry*>(entry));
+
+    default:
+        return CONSISTENT;
+    }
+}
+
+InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackKey(
+        const KeyEntry* entry) {
+    int32_t action = entry->action;
+    for (size_t i = 0; i < mKeyMementos.size(); i++) {
+        KeyMemento& memento = mKeyMementos.editItemAt(i);
+        if (memento.deviceId == entry->deviceId
+                && memento.source == entry->source
+                && memento.keyCode == entry->keyCode
+                && memento.scanCode == entry->scanCode) {
+            switch (action) {
+            case AKEY_EVENT_ACTION_UP:
+                mKeyMementos.removeAt(i);
+                return CONSISTENT;
+
+            case AKEY_EVENT_ACTION_DOWN:
+                return TOLERABLE;
+
+            default:
+                return BROKEN;
+            }
+        }
+    }
+
+    switch (action) {
+    case AKEY_EVENT_ACTION_DOWN: {
+        mKeyMementos.push();
+        KeyMemento& memento = mKeyMementos.editTop();
+        memento.deviceId = entry->deviceId;
+        memento.source = entry->source;
+        memento.keyCode = entry->keyCode;
+        memento.scanCode = entry->scanCode;
+        memento.downTime = entry->downTime;
+        return CONSISTENT;
+    }
+
+    default:
+        return BROKEN;
+    }
+}
+
+InputDispatcher::InputState::Consistency InputDispatcher::InputState::trackMotion(
+        const MotionEntry* entry) {
+    int32_t action = entry->action & AMOTION_EVENT_ACTION_MASK;
+    for (size_t i = 0; i < mMotionMementos.size(); i++) {
+        MotionMemento& memento = mMotionMementos.editItemAt(i);
+        if (memento.deviceId == entry->deviceId
+                && memento.source == entry->source) {
+            switch (action) {
+            case AMOTION_EVENT_ACTION_UP:
+            case AMOTION_EVENT_ACTION_CANCEL:
+                mMotionMementos.removeAt(i);
+                return CONSISTENT;
+
+            case AMOTION_EVENT_ACTION_DOWN:
+                return TOLERABLE;
+
+            case AMOTION_EVENT_ACTION_POINTER_DOWN:
+                if (entry->pointerCount == memento.pointerCount + 1) {
+                    memento.setPointers(entry);
+                    return CONSISTENT;
+                }
+                return BROKEN;
+
+            case AMOTION_EVENT_ACTION_POINTER_UP:
+                if (entry->pointerCount == memento.pointerCount - 1) {
+                    memento.setPointers(entry);
+                    return CONSISTENT;
+                }
+                return BROKEN;
+
+            case AMOTION_EVENT_ACTION_MOVE:
+                if (entry->pointerCount == memento.pointerCount) {
+                    return CONSISTENT;
+                }
+                return BROKEN;
+
+            default:
+                return BROKEN;
+            }
+        }
+    }
+
+    switch (action) {
+    case AMOTION_EVENT_ACTION_DOWN: {
+        mMotionMementos.push();
+        MotionMemento& memento = mMotionMementos.editTop();
+        memento.deviceId = entry->deviceId;
+        memento.source = entry->source;
+        memento.xPrecision = entry->xPrecision;
+        memento.yPrecision = entry->yPrecision;
+        memento.downTime = entry->downTime;
+        memento.setPointers(entry);
+        return CONSISTENT;
+    }
+
+    default:
+        return BROKEN;
+    }
+}
+
+void InputDispatcher::InputState::MotionMemento::setPointers(const MotionEntry* entry) {
+    pointerCount = entry->pointerCount;
+    for (uint32_t i = 0; i < entry->pointerCount; i++) {
+        pointerIds[i] = entry->pointerIds[i];
+        pointerCoords[i] = entry->lastSample->pointerCoords[i];
+    }
+}
+
+void InputDispatcher::InputState::synthesizeCancelationEvents(nsecs_t currentTime,
+        Allocator* allocator, Vector<EventEntry*>& outEvents,
+        CancelationOptions options) {
+    for (size_t i = 0; i < mKeyMementos.size(); ) {
+        const KeyMemento& memento = mKeyMementos.itemAt(i);
+        if (shouldCancelEvent(memento.source, options)) {
+            outEvents.push(allocator->obtainKeyEntry(currentTime,
+                    memento.deviceId, memento.source, 0,
+                    AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
+                    memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
+            mKeyMementos.removeAt(i);
+        } else {
+            i += 1;
+        }
+    }
+
+    for (size_t i = 0; i < mMotionMementos.size(); ) {
+        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        if (shouldCancelEvent(memento.source, options)) {
+            outEvents.push(allocator->obtainMotionEntry(currentTime,
+                    memento.deviceId, memento.source, 0,
+                    AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
+                    memento.xPrecision, memento.yPrecision, memento.downTime,
+                    memento.pointerCount, memento.pointerIds, memento.pointerCoords));
+            mMotionMementos.removeAt(i);
+        } else {
+            i += 1;
+        }
+    }
+}
+
+void InputDispatcher::InputState::clear() {
+    mKeyMementos.clear();
+    mMotionMementos.clear();
+}
+
+bool InputDispatcher::InputState::shouldCancelEvent(int32_t eventSource,
+        CancelationOptions options) {
+    switch (options) {
+    case CANCEL_POINTER_EVENTS:
+        return eventSource & AINPUT_SOURCE_CLASS_POINTER;
+    case CANCEL_NON_POINTER_EVENTS:
+        return !(eventSource & AINPUT_SOURCE_CLASS_POINTER);
+    default:
+        return true;
+    }
+}
+
+
+// --- InputDispatcher::Connection ---
+
+InputDispatcher::Connection::Connection(const sp<InputChannel>& inputChannel) :
+        status(STATUS_NORMAL), inputChannel(inputChannel), inputPublisher(inputChannel),
+        lastEventTime(LONG_LONG_MAX), lastDispatchTime(LONG_LONG_MAX) {
+}
+
+InputDispatcher::Connection::~Connection() {
+}
+
+status_t InputDispatcher::Connection::initialize() {
+    return inputPublisher.initialize();
+}
+
+const char* InputDispatcher::Connection::getStatusLabel() const {
+    switch (status) {
+    case STATUS_NORMAL:
+        return "NORMAL";
+
+    case STATUS_BROKEN:
+        return "BROKEN";
+
+    case STATUS_ZOMBIE:
+        return "ZOMBIE";
+
+    default:
+        return "UNKNOWN";
+    }
+}
+
+InputDispatcher::DispatchEntry* InputDispatcher::Connection::findQueuedDispatchEntryForEvent(
+        const EventEntry* eventEntry) const {
+    for (DispatchEntry* dispatchEntry = outboundQueue.tailSentinel.prev;
+            dispatchEntry != & outboundQueue.headSentinel; dispatchEntry = dispatchEntry->prev) {
+        if (dispatchEntry->eventEntry == eventEntry) {
+            return dispatchEntry;
+        }
+    }
+    return NULL;
+}
+
+
+// --- InputDispatcher::CommandEntry ---
+
+InputDispatcher::CommandEntry::CommandEntry() :
+    keyEntry(NULL) {
+}
+
+InputDispatcher::CommandEntry::~CommandEntry() {
+}
+
+
+// --- InputDispatcher::TouchState ---
+
+InputDispatcher::TouchState::TouchState() :
+    down(false), split(false) {
+}
+
+InputDispatcher::TouchState::~TouchState() {
+}
+
+void InputDispatcher::TouchState::reset() {
+    down = false;
+    split = false;
+    windows.clear();
+}
+
+void InputDispatcher::TouchState::copyFrom(const TouchState& other) {
+    down = other.down;
+    split = other.split;
+    windows.clear();
+    windows.appendVector(other.windows);
+}
+
+void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window,
+        int32_t targetFlags, BitSet32 pointerIds) {
+    if (targetFlags & InputTarget::FLAG_SPLIT) {
+        split = true;
+    }
+
+    for (size_t i = 0; i < windows.size(); i++) {
+        TouchedWindow& touchedWindow = windows.editItemAt(i);
+        if (touchedWindow.window == window) {
+            touchedWindow.targetFlags |= targetFlags;
+            touchedWindow.pointerIds.value |= pointerIds.value;
+            return;
+        }
+    }
+
+    windows.push();
+
+    TouchedWindow& touchedWindow = windows.editTop();
+    touchedWindow.window = window;
+    touchedWindow.targetFlags = targetFlags;
+    touchedWindow.pointerIds = pointerIds;
+    touchedWindow.channel = window->inputChannel;
+}
+
+void InputDispatcher::TouchState::removeOutsideTouchWindows() {
+    for (size_t i = 0 ; i < windows.size(); ) {
+        if (windows[i].targetFlags & InputTarget::FLAG_OUTSIDE) {
+            windows.removeAt(i);
+        } else {
+            i += 1;
+        }
+    }
+}
+
+const InputWindow* InputDispatcher::TouchState::getFirstForegroundWindow() {
+    for (size_t i = 0; i < windows.size(); i++) {
+        if (windows[i].targetFlags & InputTarget::FLAG_FOREGROUND) {
+            return windows[i].window;
+        }
+    }
+    return NULL;
+}
+
+
+// --- 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..09fce38
--- /dev/null
+++ b/libs/ui/InputManager.cpp
@@ -0,0 +1,83 @@
+//
+// 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;
+}
+
+sp<InputReaderInterface> InputManager::getReader() {
+    return mReader;
+}
+
+sp<InputDispatcherInterface> InputManager::getDispatcher() {
+    return mDispatcher;
+}
+
+} // namespace android
diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp
new file mode 100644
index 0000000..3197ab2
--- /dev/null
+++ b/libs/ui/InputReader.cpp
@@ -0,0 +1,3478 @@
+//
+// 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 "  "
+#define INDENT2 "    "
+#define INDENT3 "      "
+#define INDENT4 "        "
+
+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);
+}
+
+static inline const char* toString(bool value) {
+    return value ? "true" : "false";
+}
+
+
+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->deviceId);
+        break;
+
+    case EventHubInterface::DEVICE_REMOVED:
+        removeDevice(rawEvent->deviceId);
+        break;
+
+    case EventHubInterface::FINISHED_DEVICE_SCAN:
+        handleConfigurationChanged(rawEvent->when);
+        break;
+
+    default:
+        consumeEvent(rawEvent);
+        break;
+    }
+}
+
+void InputReader::addDevice(int32_t deviceId) {
+    String8 name = mEventHub->getDeviceName(deviceId);
+    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+
+    InputDevice* device = createDevice(deviceId, name, classes);
+    device->configure();
+
+    if (device->isIgnored()) {
+        LOGI("Device added: id=0x%x, name=%s (ignored non-input device)", deviceId, name.string());
+    } else {
+        LOGI("Device added: id=0x%x, name=%s, sources=%08x", deviceId, name.string(),
+                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;
+    }
+}
+
+void InputReader::removeDevice(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;
+    }
+
+    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;
+}
+
+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 (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
+}
+
+void InputReader::dump(String8& dump) {
+    mEventHub->dump(dump);
+    dump.append("\n");
+
+    dump.append("Input Reader State:\n");
+
+    { // acquire device registry reader lock
+        RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+        for (size_t i = 0; i < mDevices.size(); i++) {
+            mDevices.valueAt(i)->dump(dump);
+        }
+    } // 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();
+}
+
+static void dumpMotionRange(String8& dump, const InputDeviceInfo& deviceInfo,
+        int32_t rangeType, const char* name) {
+    const InputDeviceInfo::MotionRange* range = deviceInfo.getMotionRange(rangeType);
+    if (range) {
+        dump.appendFormat(INDENT3 "%s: min=%0.3f, max=%0.3f, flat=%0.3f, fuzz=%0.3f\n",
+                name, range->min, range->max, range->flat, range->fuzz);
+    }
+}
+
+void InputDevice::dump(String8& dump) {
+    InputDeviceInfo deviceInfo;
+    getDeviceInfo(& deviceInfo);
+
+    dump.appendFormat(INDENT "Device 0x%x: %s\n", deviceInfo.getId(),
+            deviceInfo.getName().string());
+    dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources());
+    dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType());
+    if (!deviceInfo.getMotionRanges().isEmpty()) {
+        dump.append(INDENT2 "Motion Ranges:\n");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_X, "X");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_Y, "Y");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_PRESSURE, "Pressure");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_SIZE, "Size");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MAJOR, "TouchMajor");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOUCH_MINOR, "TouchMinor");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MAJOR, "ToolMajor");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_TOOL_MINOR, "ToolMinor");
+        dumpMotionRange(dump, deviceInfo, AINPUT_MOTION_RANGE_ORIENTATION, "Orientation");
+    }
+
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->dump(dump);
+    }
+}
+
+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::dump(String8& dump) {
+}
+
+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;
+}
+
+
+// --- 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) {
+    getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
+}
+
+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::dump(String8& dump) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+        dump.append(INDENT2 "Keyboard Input Mapper:\n");
+        dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
+        dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
+        dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
+        dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
+        dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
+    } // release lock
+}
+
+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.itemAt(keyDownIndex).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.itemAt(keyDownIndex).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();
+    }
+
+    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+            down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
+            AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, 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::dump(String8& dump) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+        dump.append(INDENT2 "Trackball Input Mapper:\n");
+        dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
+        dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
+        dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+        dump.appendFormat(INDENT3 "Down: %s\n", toString(mLocked.down));
+        dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
+    } // release lock
+}
+
+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
+
+    int32_t metaState = mContext->getGlobalMetaState();
+    int32_t pointerId = 0;
+    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, 0,
+            motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+            1, &pointerId, &pointerCoords, mXPrecision, mYPrecision, downTime);
+
+    mAccumulator.clear();
+}
+
+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.haveTouchSize) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+                    mLocked.orientedRanges.touchMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+                    mLocked.orientedRanges.touchMinor);
+        }
+
+        if (mLocked.orientedRanges.haveToolSize) {
+            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::dump(String8& dump) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+        dump.append(INDENT2 "Touch Input Mapper:\n");
+        dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId);
+        dumpParameters(dump);
+        dumpVirtualKeysLocked(dump);
+        dumpRawAxes(dump);
+        dumpCalibration(dump);
+        dumpSurfaceLocked(dump);
+        dump.appendFormat(INDENT3 "Translation and Scaling Factors:");
+        dump.appendFormat(INDENT4 "XOrigin: %d\n", mLocked.xOrigin);
+        dump.appendFormat(INDENT4 "YOrigin: %d\n", mLocked.yOrigin);
+        dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
+        dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
+        dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
+        dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
+        dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
+        dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
+        dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
+        dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
+        dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
+        dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
+        dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
+        dump.appendFormat(INDENT4 "OrientationSCale: %0.3f\n", mLocked.orientationScale);
+    } // 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.haveTouchSize = false;
+    mLocked.orientedRanges.haveToolSize = false;
+    mLocked.orientedRanges.haveOrientation = false;
+}
+
+void TouchInputMapper::configure() {
+    InputMapper::configure();
+
+    // Configure basic parameters.
+    configureParameters();
+
+    // Configure absolute axis information.
+    configureRawAxes();
+
+    // Prepare input device calibration.
+    parseCalibration();
+    resolveCalibration();
+
+    { // 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::dumpParameters(String8& dump) {
+    dump.appendFormat(INDENT3 "UseBadTouchFilter: %s\n",
+            toString(mParameters.useBadTouchFilter));
+    dump.appendFormat(INDENT3 "UseAveragingTouchFilter: %s\n",
+            toString(mParameters.useAveragingTouchFilter));
+    dump.appendFormat(INDENT3 "UseJumpyTouchFilter: %s\n",
+            toString(mParameters.useJumpyTouchFilter));
+}
+
+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();
+}
+
+static void dumpAxisInfo(String8& dump, RawAbsoluteAxisInfo axis, const char* name) {
+    if (axis.valid) {
+        dump.appendFormat(INDENT4 "%s: min=%d, max=%d, flat=%d, fuzz=%d\n",
+                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
+    } else {
+        dump.appendFormat(INDENT4 "%s: unknown range\n", name);
+    }
+}
+
+void TouchInputMapper::dumpRawAxes(String8& dump) {
+    dump.append(INDENT3 "Raw Axes:\n");
+    dumpAxisInfo(dump, mRawAxes.x, "X");
+    dumpAxisInfo(dump, mRawAxes.y, "Y");
+    dumpAxisInfo(dump, mRawAxes.pressure, "Pressure");
+    dumpAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
+    dumpAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
+    dumpAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
+    dumpAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
+    dumpAxisInfo(dump, 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 reconfigured: id=0x%x, name=%s, display size is now %dx%d",
+                getDeviceId(), getDeviceName().string(), width, height);
+
+        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.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
+            mLocked.orientedRanges.haveTouchSize = 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.
+        mLocked.toolSizeLinearScale = 0;
+        mLocked.toolSizeLinearBias = 0;
+        mLocked.toolSizeAreaScale = 0;
+        mLocked.toolSizeAreaBias = 0;
+        if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
+            if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
+                if (mCalibration.haveToolSizeLinearScale) {
+                    mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
+                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.toolSizeLinearScale = float(min(width, height))
+                            / mRawAxes.toolMajor.maxValue;
+                }
+
+                if (mCalibration.haveToolSizeLinearBias) {
+                    mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+                }
+            } else if (mCalibration.toolSizeCalibration ==
+                    Calibration::TOOL_SIZE_CALIBRATION_AREA) {
+                if (mCalibration.haveToolSizeLinearScale) {
+                    mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
+                } else {
+                    mLocked.toolSizeLinearScale = min(width, height);
+                }
+
+                if (mCalibration.haveToolSizeLinearBias) {
+                    mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+                }
+
+                if (mCalibration.haveToolSizeAreaScale) {
+                    mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
+                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
+                }
+
+                if (mCalibration.haveToolSizeAreaBias) {
+                    mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
+                }
+            }
+
+            mLocked.orientedRanges.haveToolSize = 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.
+        mLocked.pressureScale = 0;
+        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();
+            }
+
+            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.
+        mLocked.sizeScale = 0;
+        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
+            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
+        mLocked.orientationScale = 0;
+        if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
+            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::dumpSurfaceLocked(String8& dump) {
+    dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
+    dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
+    dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
+}
+
+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;
+
+    }
+}
+
+void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
+    if (!mLocked.virtualKeys.isEmpty()) {
+        dump.append(INDENT3 "Virtual Keys:\n");
+
+        for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
+            dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
+                    "hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
+                    i, virtualKey.scanCode, virtualKey.keyCode,
+                    virtualKey.hitLeft, virtualKey.hitRight,
+                    virtualKey.hitTop, virtualKey.hitBottom);
+        }
+    }
+}
+
+void TouchInputMapper::parseCalibration() {
+    const InputDeviceCalibration& in = getDevice()->getCalibration();
+    Calibration& out = mCalibration;
+
+    // Touch Size
+    out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT;
+    String8 touchSizeCalibrationString;
+    if (in.tryGetProperty(String8("touch.touchSize.calibration"), touchSizeCalibrationString)) {
+        if (touchSizeCalibrationString == "none") {
+            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_NONE;
+        } else if (touchSizeCalibrationString == "geometric") {
+            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC;
+        } else if (touchSizeCalibrationString == "pressure") {
+            out.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
+        } else if (touchSizeCalibrationString != "default") {
+            LOGW("Invalid value for touch.touchSize.calibration: '%s'",
+                    touchSizeCalibrationString.string());
+        }
+    }
+
+    // Tool Size
+    out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_DEFAULT;
+    String8 toolSizeCalibrationString;
+    if (in.tryGetProperty(String8("touch.toolSize.calibration"), toolSizeCalibrationString)) {
+        if (toolSizeCalibrationString == "none") {
+            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
+        } else if (toolSizeCalibrationString == "geometric") {
+            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC;
+        } else if (toolSizeCalibrationString == "linear") {
+            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
+        } else if (toolSizeCalibrationString == "area") {
+            out.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_AREA;
+        } else if (toolSizeCalibrationString != "default") {
+            LOGW("Invalid value for touch.toolSize.calibration: '%s'",
+                    toolSizeCalibrationString.string());
+        }
+    }
+
+    out.haveToolSizeLinearScale = in.tryGetProperty(String8("touch.toolSize.linearScale"),
+            out.toolSizeLinearScale);
+    out.haveToolSizeLinearBias = in.tryGetProperty(String8("touch.toolSize.linearBias"),
+            out.toolSizeLinearBias);
+    out.haveToolSizeAreaScale = in.tryGetProperty(String8("touch.toolSize.areaScale"),
+            out.toolSizeAreaScale);
+    out.haveToolSizeAreaBias = in.tryGetProperty(String8("touch.toolSize.areaBias"),
+            out.toolSizeAreaBias);
+    out.haveToolSizeIsSummed = in.tryGetProperty(String8("touch.toolSize.isSummed"),
+            out.toolSizeIsSummed);
+
+    // Pressure
+    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
+    String8 pressureCalibrationString;
+    if (in.tryGetProperty(String8("touch.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 touch.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("touch.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 touch.size.calibration: '%s'",
+                    sizeCalibrationString.string());
+        }
+    }
+
+    // Orientation
+    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
+    String8 orientationCalibrationString;
+    if (in.tryGetProperty(String8("touch.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 touch.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 Size
+    switch (mCalibration.toolSizeCalibration) {
+    case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
+        } else {
+            mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Touch Size
+    switch (mCalibration.touchSizeCalibration) {
+    case Calibration::TOUCH_SIZE_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
+                && mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
+            mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE;
+        } else {
+            mCalibration.touchSizeCalibration = Calibration::TOUCH_SIZE_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::dumpCalibration(String8& dump) {
+    dump.append(INDENT3 "Calibration:\n");
+
+    // Touch Size
+    switch (mCalibration.touchSizeCalibration) {
+    case Calibration::TOUCH_SIZE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.touchSize.calibration: none\n");
+        break;
+    case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
+        dump.append(INDENT4 "touch.touchSize.calibration: geometric\n");
+        break;
+    case Calibration::TOUCH_SIZE_CALIBRATION_PRESSURE:
+        dump.append(INDENT4 "touch.touchSize.calibration: pressure\n");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Tool Size
+    switch (mCalibration.toolSizeCalibration) {
+    case Calibration::TOOL_SIZE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.toolSize.calibration: none\n");
+        break;
+    case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
+        dump.append(INDENT4 "touch.toolSize.calibration: geometric\n");
+        break;
+    case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
+        dump.append(INDENT4 "touch.toolSize.calibration: linear\n");
+        break;
+    case Calibration::TOOL_SIZE_CALIBRATION_AREA:
+        dump.append(INDENT4 "touch.toolSize.calibration: area\n");
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.haveToolSizeLinearScale) {
+        dump.appendFormat(INDENT4 "touch.toolSize.linearScale: %0.3f\n",
+                mCalibration.toolSizeLinearScale);
+    }
+
+    if (mCalibration.haveToolSizeLinearBias) {
+        dump.appendFormat(INDENT4 "touch.toolSize.linearBias: %0.3f\n",
+                mCalibration.toolSizeLinearBias);
+    }
+
+    if (mCalibration.haveToolSizeAreaScale) {
+        dump.appendFormat(INDENT4 "touch.toolSize.areaScale: %0.3f\n",
+                mCalibration.toolSizeAreaScale);
+    }
+
+    if (mCalibration.haveToolSizeAreaBias) {
+        dump.appendFormat(INDENT4 "touch.toolSize.areaBias: %0.3f\n",
+                mCalibration.toolSizeAreaBias);
+    }
+
+    if (mCalibration.haveToolSizeIsSummed) {
+        dump.appendFormat(INDENT4 "touch.toolSize.isSummed: %d\n",
+                mCalibration.toolSizeIsSummed);
+    }
+
+    // Pressure
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.pressure.calibration: none\n");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+        dump.append(INDENT4 "touch.pressure.calibration: physical\n");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+        dump.append(INDENT4 "touch.pressure.calibration: amplitude\n");
+        break;
+    default:
+        assert(false);
+    }
+
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        dump.append(INDENT4 "touch.pressure.source: pressure\n");
+        break;
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        dump.append(INDENT4 "touch.pressure.source: touch\n");
+        break;
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.havePressureScale) {
+        dump.appendFormat(INDENT4 "touch.pressure.scale: %0.3f\n",
+                mCalibration.pressureScale);
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.size.calibration: none\n");
+        break;
+    case Calibration::SIZE_CALIBRATION_NORMALIZED:
+        dump.append(INDENT4 "touch.size.calibration: normalized\n");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_NONE:
+        dump.append(INDENT4 "touch.orientation.calibration: none\n");
+        break;
+    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+        dump.append(INDENT4 "touch.orientation.calibration: interpolated\n");
+        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) {
+    uint32_t policyFlags = 0;
+
+    // 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",
+                        mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.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",
+                    mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
+#endif
+            keyEventAction = AKEY_EVENT_ACTION_UP;
+            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+                    | AKEY_EVENT_FLAG_CANCELED;
+
+            // Check whether the pointer moved inside the display area where we should
+            // start a new stroke.
+            int32_t x = mCurrentTouch.pointers[0].x;
+            int32_t y = mCurrentTouch.pointers[0].y;
+            if (isPointInsideSurfaceLocked(x, y)) {
+                mLastTouch.clear();
+                touchResult = DISPATCH_TOUCH;
+            } else {
+                touchResult = DROP_STROKE;
+            }
+        } 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",
+                                    mLocked.currentVirtualKey.keyCode,
+                                    mLocked.currentVirtualKey.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.
+    int32_t metaState = mContext->getGlobalMetaState();
+    policyFlags |= POLICY_FLAG_VIRTUAL;
+    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+    return touchResult;
+}
+
+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 and pointers moving
+        // all at the same time.
+        BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
+        BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
+        BitSet32 activeIdBits(lastIdBits.value);
+        uint32_t pointerCount = lastPointerCount;
+
+        // Produce an intermediate representation of the touch data that consists of the
+        // old location of pointers that have just gone up and the new location of pointers that
+        // have just moved but omits the location of pointers that have just gone down.
+        TouchData interimTouch;
+        interimTouch.copyFrom(mLastTouch);
+
+        BitSet32 moveIdBits(lastIdBits.value & currentIdBits.value);
+        bool moveNeeded = false;
+        while (!moveIdBits.isEmpty()) {
+            uint32_t moveId = moveIdBits.firstMarkedBit();
+            moveIdBits.clearBit(moveId);
+
+            int32_t oldIndex = mLastTouch.idToIndex[moveId];
+            int32_t newIndex = mCurrentTouch.idToIndex[moveId];
+            if (mLastTouch.pointers[oldIndex] != mCurrentTouch.pointers[newIndex]) {
+                interimTouch.pointers[oldIndex] = mCurrentTouch.pointers[newIndex];
+                moveNeeded = true;
+            }
+        }
+
+        // Dispatch pointer up events using the interim pointer locations.
+        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, &interimTouch,
+                    oldActiveIdBits, upId, pointerCount, motionEventAction);
+            pointerCount -= 1;
+        }
+
+        // Dispatch move events if any of the remaining pointers moved from their old locations.
+        // Although applications receive new locations as part of individual pointer up
+        // events, they do not generally handle them except when presented in a move event.
+        if (moveNeeded) {
+            dispatchTouch(when, policyFlags, &mCurrentTouch,
+                    activeIdBits, -1, pointerCount, AMOTION_EVENT_ACTION_MOVE);
+        }
+
+        // Dispatch pointer down events using the new pointer locations.
+        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.toolSizeCalibration) {
+            case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
+                toolMajor = in.toolMajor * mLocked.geometricScale;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor * mLocked.geometricScale;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
+                toolMajor = in.toolMajor != 0
+                        ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
+                        : 0;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor != 0
+                            ? in.toolMinor * mLocked.toolSizeLinearScale
+                                    + mLocked.toolSizeLinearBias
+                            : 0;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            case Calibration::TOOL_SIZE_CALIBRATION_AREA:
+                if (in.toolMajor != 0) {
+                    float diameter = sqrtf(in.toolMajor
+                            * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
+                    toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
+                } else {
+                    toolMajor = 0;
+                }
+                toolMinor = toolMajor;
+                break;
+            default:
+                toolMajor = 0;
+                toolMinor = 0;
+                break;
+            }
+
+            if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
+                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.touchSizeCalibration) {
+            case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
+                touchMajor = in.touchMajor * mLocked.geometricScale;
+                if (mRawAxes.touchMinor.valid) {
+                    touchMinor = in.touchMinor * mLocked.geometricScale;
+                } else {
+                    touchMinor = touchMajor;
+                }
+                break;
+            case Calibration::TOUCH_SIZE_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(), getSources(), 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 pressure to indicate
+                // a pointer going 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",
+                            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..2c6346e
--- /dev/null
+++ b/libs/ui/InputTransport.cpp
@@ -0,0 +1,702 @@
+//
+// 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;
+    do {
+        nWrite = ::write(mSendPipeFd, & signal, 1);
+    } while (nWrite == -1 && errno == EINTR);
+
+    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;
+    do {
+        nRead = ::read(mReceivePipeFd, outSignal, 1);
+    } while (nRead == -1 && errno == EINTR);
+
+    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/Region.cpp b/libs/ui/Region.cpp
index 12db908..1994f6a 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -289,7 +289,7 @@
     void flushSpan() {
         bool merge = false;
         if (tail-head == ssize_t(span.size())) {
-            Rect const* p = cur;
+            Rect const* p = span.editArray();
             Rect const* q = head;
             if (p->top == q->bottom) {
                 merge = true;
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 6cc4a5a..aa017b9 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -1,16 +1,51 @@
+# 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 \
+    InputReader_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..8874dfe
--- /dev/null
+++ b/libs/ui/tests/InputDispatcher_test.cpp
@@ -0,0 +1,226 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputDispatcher.h>
+#include <gtest/gtest.h>
+#include <linux/input.h>
+
+namespace android {
+
+// An arbitrary time value.
+static const nsecs_t ARBITRARY_TIME = 1234;
+
+// An arbitrary device id.
+static const int32_t DEVICE_ID = 1;
+
+// An arbitrary injector pid / uid pair that has permission to inject events.
+static const int32_t INJECTOR_PID = 999;
+static const int32_t INJECTOR_UID = 1001;
+
+
+// --- FakeInputDispatcherPolicy ---
+
+class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
+protected:
+    virtual ~FakeInputDispatcherPolicy() {
+    }
+
+public:
+    FakeInputDispatcherPolicy() {
+    }
+
+private:
+    virtual void notifyConfigurationChanged(nsecs_t when) {
+    }
+
+    virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
+            const sp<InputChannel>& inputChannel) {
+        return 0;
+    }
+
+    virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
+    }
+
+    virtual nsecs_t getKeyRepeatTimeout() {
+        return 500 * 1000000LL;
+    }
+
+    virtual nsecs_t getKeyRepeatDelay() {
+        return 50 * 1000000LL;
+    }
+
+    virtual int32_t getMaxEventsPerSecond() {
+        return 60;
+    }
+
+    virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
+            int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
+            uint32_t& policyFlags) {
+    }
+
+    virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
+    }
+
+    virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
+            const KeyEvent* keyEvent, uint32_t policyFlags) {
+        return false;
+    }
+
+    virtual void notifySwitch(nsecs_t when,
+            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
+    }
+
+    virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
+    }
+
+    virtual bool checkInjectEventsPermissionNonReentrant(
+            int32_t injectorPid, int32_t injectorUid) {
+        return false;
+    }
+};
+
+
+// --- InputDispatcherTest ---
+
+class InputDispatcherTest : public testing::Test {
+protected:
+    sp<FakeInputDispatcherPolicy> mFakePolicy;
+    sp<InputDispatcher> mDispatcher;
+
+    virtual void SetUp() {
+        mFakePolicy = new FakeInputDispatcherPolicy();
+        mDispatcher = new InputDispatcher(mFakePolicy);
+    }
+
+    virtual void TearDown() {
+        mFakePolicy.clear();
+        mDispatcher.clear();
+    }
+};
+
+
+TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesKeyEvents) {
+    KeyEvent event;
+
+    // Rejects undefined key actions.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
+            /*action*/ -1, 0,
+            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject key events with undefined action.";
+
+    // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
+            AKEY_EVENT_ACTION_MULTIPLE, 0,
+            AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject key events with ACTION_MULTIPLE.";
+}
+
+TEST_F(InputDispatcherTest, InjectInputEvent_ValidatesMotionEvents) {
+    MotionEvent event;
+    int32_t pointerIds[MAX_POINTERS + 1];
+    PointerCoords pointerCoords[MAX_POINTERS + 1];
+    for (int i = 0; i <= MAX_POINTERS; i++) {
+        pointerIds[i] = i;
+    }
+
+    // Rejects undefined motion actions.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            /*action*/ -1, 0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with undefined action.";
+
+    // Rejects pointer down with invalid index.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with pointer down index too large.";
+
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_POINTER_DOWN | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with pointer down index too small.";
+
+    // Rejects pointer up with invalid index.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with pointer up index too large.";
+
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_POINTER_UP | (-1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with pointer up index too small.";
+
+    // Rejects motion events with invalid number of pointers.
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 0, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with 0 pointers.";
+
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ MAX_POINTERS + 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with more than MAX_POINTERS pointers.";
+
+    // Rejects motion events with invalid pointer ids.
+    pointerIds[0] = -1;
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with pointer ids less than 0.";
+
+    pointerIds[0] = MAX_POINTER_ID + 1;
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 1, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with pointer ids greater than MAX_POINTER_ID.";
+
+    // Rejects motion events with duplicate pointer ids.
+    pointerIds[0] = 1;
+    pointerIds[1] = 1;
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_TOUCHSCREEN,
+            AMOTION_EVENT_ACTION_DOWN, 0, 0, AMETA_NONE, 0, 0, 0, 0,
+            ARBITRARY_TIME, ARBITRARY_TIME,
+            /*pointerCount*/ 2, pointerIds, pointerCoords);
+    ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(&event,
+            INJECTOR_PID, INJECTOR_UID, INPUT_EVENT_INJECTION_SYNC_NONE, 0))
+            << "Should reject motion events with duplicate pointer ids.";
+}
+
+} // 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/InputReader_test.cpp b/libs/ui/tests/InputReader_test.cpp
new file mode 100644
index 0000000..de4b05a
--- /dev/null
+++ b/libs/ui/tests/InputReader_test.cpp
@@ -0,0 +1,3368 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputReader.h>
+#include <utils/List.h>
+#include <gtest/gtest.h>
+#include <math.h>
+
+namespace android {
+
+// An arbitrary time value.
+static const nsecs_t ARBITRARY_TIME = 1234;
+
+// Arbitrary display properties.
+static const int32_t DISPLAY_ID = 0;
+static const int32_t DISPLAY_WIDTH = 480;
+static const int32_t DISPLAY_HEIGHT = 800;
+
+// Error tolerance for floating point assertions.
+static const float EPSILON = 0.001f;
+
+template<typename T>
+static inline T min(T a, T b) {
+    return a < b ? a : b;
+}
+
+static inline float avg(float x, float y) {
+    return (x + y) / 2;
+}
+
+
+// --- FakeInputReaderPolicy ---
+
+class FakeInputReaderPolicy : public InputReaderPolicyInterface {
+    struct DisplayInfo {
+        int32_t width;
+        int32_t height;
+        int32_t orientation;
+    };
+
+    KeyedVector<int32_t, DisplayInfo> mDisplayInfos;
+    bool mFilterTouchEvents;
+    bool mFilterJumpyTouchEvents;
+    KeyedVector<String8, Vector<VirtualKeyDefinition> > mVirtualKeyDefinitions;
+    KeyedVector<String8, InputDeviceCalibration> mInputDeviceCalibrations;
+    Vector<String8> mExcludedDeviceNames;
+
+protected:
+    virtual ~FakeInputReaderPolicy() { }
+
+public:
+    FakeInputReaderPolicy() :
+            mFilterTouchEvents(false), mFilterJumpyTouchEvents(false) {
+    }
+
+    void removeDisplayInfo(int32_t displayId) {
+        mDisplayInfos.removeItem(displayId);
+    }
+
+    void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
+        removeDisplayInfo(displayId);
+
+        DisplayInfo info;
+        info.width = width;
+        info.height = height;
+        info.orientation = orientation;
+        mDisplayInfos.add(displayId, info);
+    }
+
+    void setFilterTouchEvents(bool enabled) {
+        mFilterTouchEvents = enabled;
+    }
+
+    void setFilterJumpyTouchEvents(bool enabled) {
+        mFilterJumpyTouchEvents = enabled;
+    }
+
+    void addInputDeviceCalibration(const String8& deviceName,
+            const InputDeviceCalibration& calibration) {
+        mInputDeviceCalibrations.add(deviceName, calibration);
+    }
+
+    void addInputDeviceCalibrationProperty(const String8& deviceName,
+            const String8& key, const String8& value) {
+        ssize_t index = mInputDeviceCalibrations.indexOfKey(deviceName);
+        if (index < 0) {
+            index = mInputDeviceCalibrations.add(deviceName, InputDeviceCalibration());
+        }
+        mInputDeviceCalibrations.editValueAt(index).addProperty(key, value);
+    }
+
+    void addVirtualKeyDefinition(const String8& deviceName,
+            const VirtualKeyDefinition& definition) {
+        if (mVirtualKeyDefinitions.indexOfKey(deviceName) < 0) {
+            mVirtualKeyDefinitions.add(deviceName, Vector<VirtualKeyDefinition>());
+        }
+
+        mVirtualKeyDefinitions.editValueFor(deviceName).push(definition);
+    }
+
+    void addExcludedDeviceName(const String8& deviceName) {
+        mExcludedDeviceNames.push(deviceName);
+    }
+
+private:
+    virtual bool getDisplayInfo(int32_t displayId,
+            int32_t* width, int32_t* height, int32_t* orientation) {
+        ssize_t index = mDisplayInfos.indexOfKey(displayId);
+        if (index >= 0) {
+            const DisplayInfo& info = mDisplayInfos.valueAt(index);
+            if (width) {
+                *width = info.width;
+            }
+            if (height) {
+                *height = info.height;
+            }
+            if (orientation) {
+                *orientation = info.orientation;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    virtual bool filterTouchEvents() {
+        return mFilterTouchEvents;
+    }
+
+    virtual bool filterJumpyTouchEvents() {
+        return mFilterJumpyTouchEvents;
+    }
+
+    virtual void getVirtualKeyDefinitions(const String8& deviceName,
+            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
+        ssize_t index = mVirtualKeyDefinitions.indexOfKey(deviceName);
+        if (index >= 0) {
+            outVirtualKeyDefinitions.appendVector(mVirtualKeyDefinitions.valueAt(index));
+        }
+    }
+
+    virtual void getInputDeviceCalibration(const String8& deviceName,
+            InputDeviceCalibration& outCalibration) {
+        ssize_t index = mInputDeviceCalibrations.indexOfKey(deviceName);
+        if (index >= 0) {
+            outCalibration = mInputDeviceCalibrations.valueAt(index);
+        }
+    }
+
+    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
+        outExcludedDeviceNames.appendVector(mExcludedDeviceNames);
+    }
+};
+
+
+// --- FakeInputDispatcher ---
+
+class FakeInputDispatcher : public InputDispatcherInterface {
+public:
+    struct NotifyConfigurationChangedArgs {
+        nsecs_t eventTime;
+    };
+
+    struct NotifyKeyArgs {
+        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;
+    };
+
+    struct NotifyMotionArgs {
+        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;
+        Vector<int32_t> pointerIds;
+        Vector<PointerCoords> pointerCoords;
+        float xPrecision;
+        float yPrecision;
+        nsecs_t downTime;
+    };
+
+    struct NotifySwitchArgs {
+        nsecs_t when;
+        int32_t switchCode;
+        int32_t switchValue;
+        uint32_t policyFlags;
+    };
+
+private:
+    List<NotifyConfigurationChangedArgs> mNotifyConfigurationChangedArgs;
+    List<NotifyKeyArgs> mNotifyKeyArgs;
+    List<NotifyMotionArgs> mNotifyMotionArgs;
+    List<NotifySwitchArgs> mNotifySwitchArgs;
+
+protected:
+    virtual ~FakeInputDispatcher() { }
+
+public:
+    FakeInputDispatcher() {
+    }
+
+    void assertNotifyConfigurationChangedWasCalled(NotifyConfigurationChangedArgs* outArgs = NULL) {
+        ASSERT_FALSE(mNotifyConfigurationChangedArgs.empty())
+                << "Expected notifyConfigurationChanged() to have been called.";
+        if (outArgs) {
+            *outArgs = *mNotifyConfigurationChangedArgs.begin();
+        }
+        mNotifyConfigurationChangedArgs.erase(mNotifyConfigurationChangedArgs.begin());
+    }
+
+    void assertNotifyKeyWasCalled(NotifyKeyArgs* outArgs = NULL) {
+        ASSERT_FALSE(mNotifyKeyArgs.empty())
+                << "Expected notifyKey() to have been called.";
+        if (outArgs) {
+            *outArgs = *mNotifyKeyArgs.begin();
+        }
+        mNotifyKeyArgs.erase(mNotifyKeyArgs.begin());
+    }
+
+    void assertNotifyKeyWasNotCalled() {
+        ASSERT_TRUE(mNotifyKeyArgs.empty())
+                << "Expected notifyKey() to not have been called.";
+    }
+
+    void assertNotifyMotionWasCalled(NotifyMotionArgs* outArgs = NULL) {
+        ASSERT_FALSE(mNotifyMotionArgs.empty())
+                << "Expected notifyMotion() to have been called.";
+        if (outArgs) {
+            *outArgs = *mNotifyMotionArgs.begin();
+        }
+        mNotifyMotionArgs.erase(mNotifyMotionArgs.begin());
+    }
+
+    void assertNotifyMotionWasNotCalled() {
+        ASSERT_TRUE(mNotifyMotionArgs.empty())
+                << "Expected notifyMotion() to not have been called.";
+    }
+
+    void assertNotifySwitchWasCalled(NotifySwitchArgs* outArgs = NULL) {
+        ASSERT_FALSE(mNotifySwitchArgs.empty())
+                << "Expected notifySwitch() to have been called.";
+        if (outArgs) {
+            *outArgs = *mNotifySwitchArgs.begin();
+        }
+        mNotifySwitchArgs.erase(mNotifySwitchArgs.begin());
+    }
+
+private:
+    virtual void notifyConfigurationChanged(nsecs_t eventTime) {
+        NotifyConfigurationChangedArgs args;
+        args.eventTime = eventTime;
+        mNotifyConfigurationChangedArgs.push_back(args);
+    }
+
+    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) {
+        NotifyKeyArgs args;
+        args.eventTime = eventTime;
+        args.deviceId = deviceId;
+        args.source = source;
+        args.policyFlags = policyFlags;
+        args.action = action;
+        args.flags = flags;
+        args.keyCode = keyCode;
+        args.scanCode = scanCode;
+        args.metaState = metaState;
+        args.downTime = downTime;
+        mNotifyKeyArgs.push_back(args);
+    }
+
+    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) {
+        NotifyMotionArgs args;
+        args.eventTime = eventTime;
+        args.deviceId = deviceId;
+        args.source = source;
+        args.policyFlags = policyFlags;
+        args.action = action;
+        args.flags = flags;
+        args.metaState = metaState;
+        args.edgeFlags = edgeFlags;
+        args.pointerCount = pointerCount;
+        args.pointerIds.clear();
+        args.pointerIds.appendArray(pointerIds, pointerCount);
+        args.pointerCoords.clear();
+        args.pointerCoords.appendArray(pointerCoords, pointerCount);
+        args.xPrecision = xPrecision;
+        args.yPrecision = yPrecision;
+        args.downTime = downTime;
+        mNotifyMotionArgs.push_back(args);
+    }
+
+    virtual void notifySwitch(nsecs_t when,
+            int32_t switchCode, int32_t switchValue, uint32_t policyFlags) {
+        NotifySwitchArgs args;
+        args.when = when;
+        args.switchCode = switchCode;
+        args.switchValue = switchValue;
+        args.policyFlags = policyFlags;
+        mNotifySwitchArgs.push_back(args);
+    }
+
+    virtual void dump(String8& dump) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+    }
+
+    virtual void dispatchOnce() {
+        ADD_FAILURE() << "Should never be called by input reader.";
+    }
+
+    virtual int32_t injectInputEvent(const InputEvent* event,
+            int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+        return INPUT_EVENT_INJECTION_FAILED;
+    }
+
+    virtual void setInputWindows(const Vector<InputWindow>& inputWindows) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+    }
+
+    virtual void setFocusedApplication(const InputApplication* inputApplication) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+    }
+
+    virtual void setInputDispatchMode(bool enabled, bool frozen) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+    }
+
+    virtual status_t registerInputChannel(const sp<InputChannel>& inputChannel, bool monitor) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+        return 0;
+    }
+
+    virtual status_t unregisterInputChannel(const sp<InputChannel>& inputChannel) {
+        ADD_FAILURE() << "Should never be called by input reader.";
+        return 0;
+    }
+};
+
+
+// --- FakeEventHub ---
+
+class FakeEventHub : public EventHubInterface {
+    struct KeyInfo {
+        int32_t keyCode;
+        uint32_t flags;
+    };
+
+    struct Device {
+        String8 name;
+        uint32_t classes;
+        KeyedVector<int, RawAbsoluteAxisInfo> axes;
+        KeyedVector<int32_t, int32_t> keyCodeStates;
+        KeyedVector<int32_t, int32_t> scanCodeStates;
+        KeyedVector<int32_t, int32_t> switchStates;
+        KeyedVector<int32_t, KeyInfo> keys;
+
+        Device(const String8& name, uint32_t classes) :
+                name(name), classes(classes) {
+        }
+    };
+
+    KeyedVector<int32_t, Device*> mDevices;
+    Vector<String8> mExcludedDevices;
+    List<RawEvent> mEvents;
+
+protected:
+    virtual ~FakeEventHub() {
+        for (size_t i = 0; i < mDevices.size(); i++) {
+            delete mDevices.valueAt(i);
+        }
+    }
+
+public:
+    FakeEventHub() { }
+
+    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+        Device* device = new Device(name, classes);
+        mDevices.add(deviceId, device);
+
+        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0, 0, 0);
+    }
+
+    void removeDevice(int32_t deviceId) {
+        delete mDevices.valueFor(deviceId);
+        mDevices.removeItem(deviceId);
+
+        enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_REMOVED, 0, 0, 0, 0);
+    }
+
+    void finishDeviceScan() {
+        enqueueEvent(ARBITRARY_TIME, 0, EventHubInterface::FINISHED_DEVICE_SCAN, 0, 0, 0, 0);
+    }
+
+    void addAxis(int32_t deviceId, int axis,
+            int32_t minValue, int32_t maxValue, int flat, int fuzz) {
+        Device* device = getDevice(deviceId);
+
+        RawAbsoluteAxisInfo info;
+        info.valid = true;
+        info.minValue = minValue;
+        info.maxValue = maxValue;
+        info.flat = flat;
+        info.fuzz = fuzz;
+        device->axes.add(axis, info);
+    }
+
+    void setKeyCodeState(int32_t deviceId, int32_t keyCode, int32_t state) {
+        Device* device = getDevice(deviceId);
+        device->keyCodeStates.replaceValueFor(keyCode, state);
+    }
+
+    void setScanCodeState(int32_t deviceId, int32_t scanCode, int32_t state) {
+        Device* device = getDevice(deviceId);
+        device->scanCodeStates.replaceValueFor(scanCode, state);
+    }
+
+    void setSwitchState(int32_t deviceId, int32_t switchCode, int32_t state) {
+        Device* device = getDevice(deviceId);
+        device->switchStates.replaceValueFor(switchCode, state);
+    }
+
+    void addKey(int32_t deviceId, int32_t scanCode, int32_t keyCode, uint32_t flags) {
+        Device* device = getDevice(deviceId);
+        KeyInfo info;
+        info.keyCode = keyCode;
+        info.flags = flags;
+        device->keys.add(scanCode, info);
+    }
+
+    Vector<String8>& getExcludedDevices() {
+        return mExcludedDevices;
+    }
+
+    void enqueueEvent(nsecs_t when, int32_t deviceId, int32_t type,
+            int32_t scanCode, int32_t keyCode, int32_t value, uint32_t flags) {
+        RawEvent event;
+        event.when = when;
+        event.deviceId = deviceId;
+        event.type = type;
+        event.scanCode = scanCode;
+        event.keyCode = keyCode;
+        event.value = value;
+        event.flags = flags;
+        mEvents.push_back(event);
+    }
+
+    void assertQueueIsEmpty() {
+        ASSERT_EQ(size_t(0), mEvents.size())
+                << "Expected the event queue to be empty (fully consumed).";
+    }
+
+private:
+    Device* getDevice(int32_t deviceId) const {
+        ssize_t index = mDevices.indexOfKey(deviceId);
+        return index >= 0 ? mDevices.valueAt(index) : NULL;
+    }
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const {
+        Device* device = getDevice(deviceId);
+        return device ? device->classes : 0;
+    }
+
+    virtual String8 getDeviceName(int32_t deviceId) const {
+        Device* device = getDevice(deviceId);
+        return device ? device->name : String8("unknown");
+    }
+
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->axes.indexOfKey(axis);
+            if (index >= 0) {
+                *outAxisInfo = device->axes.valueAt(index);
+                return OK;
+            }
+        }
+        return -1;
+    }
+
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->keys.indexOfKey(scancode);
+            if (index >= 0) {
+                if (outKeycode) {
+                    *outKeycode = device->keys.valueAt(index).keyCode;
+                }
+                if (outFlags) {
+                    *outFlags = device->keys.valueAt(index).flags;
+                }
+                return OK;
+            }
+        }
+        return NAME_NOT_FOUND;
+    }
+
+    virtual void addExcludedDevice(const char* deviceName) {
+        mExcludedDevices.add(String8(deviceName));
+    }
+
+    virtual bool getEvent(RawEvent* outEvent) {
+        if (mEvents.empty()) {
+            return false;
+        }
+
+        *outEvent = *mEvents.begin();
+        mEvents.erase(mEvents.begin());
+        return true;
+    }
+
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->scanCodeStates.indexOfKey(scanCode);
+            if (index >= 0) {
+                return device->scanCodeStates.valueAt(index);
+            }
+        }
+        return AKEY_STATE_UNKNOWN;
+    }
+
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->keyCodeStates.indexOfKey(keyCode);
+            if (index >= 0) {
+                return device->keyCodeStates.valueAt(index);
+            }
+        }
+        return AKEY_STATE_UNKNOWN;
+    }
+
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const {
+        Device* device = getDevice(deviceId);
+        if (device) {
+            ssize_t index = device->switchStates.indexOfKey(sw);
+            if (index >= 0) {
+                return device->switchStates.valueAt(index);
+            }
+        }
+        return AKEY_STATE_UNKNOWN;
+    }
+
+    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+            uint8_t* outFlags) const {
+        bool result = false;
+        Device* device = getDevice(deviceId);
+        if (device) {
+            for (size_t i = 0; i < numCodes; i++) {
+                for (size_t j = 0; j < device->keys.size(); j++) {
+                    if (keyCodes[i] == device->keys.valueAt(j).keyCode) {
+                        outFlags[i] = 1;
+                        result = true;
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    virtual void dump(String8& dump) {
+    }
+};
+
+
+// --- FakeInputReaderContext ---
+
+class FakeInputReaderContext : public InputReaderContext {
+    sp<EventHubInterface> mEventHub;
+    sp<InputReaderPolicyInterface> mPolicy;
+    sp<InputDispatcherInterface> mDispatcher;
+    int32_t mGlobalMetaState;
+    bool mUpdateGlobalMetaStateWasCalled;
+
+public:
+    FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputDispatcherInterface>& dispatcher) :
+            mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+            mGlobalMetaState(0) {
+    }
+
+    virtual ~FakeInputReaderContext() { }
+
+    void assertUpdateGlobalMetaStateWasCalled() {
+        ASSERT_TRUE(mUpdateGlobalMetaStateWasCalled)
+                << "Expected updateGlobalMetaState() to have been called.";
+        mUpdateGlobalMetaStateWasCalled = false;
+    }
+
+    void setGlobalMetaState(int32_t state) {
+        mGlobalMetaState = state;
+    }
+
+private:
+    virtual void updateGlobalMetaState() {
+        mUpdateGlobalMetaStateWasCalled = true;
+    }
+
+    virtual int32_t getGlobalMetaState() {
+        return mGlobalMetaState;
+    }
+
+    virtual EventHubInterface* getEventHub() {
+        return mEventHub.get();
+    }
+
+    virtual InputReaderPolicyInterface* getPolicy() {
+        return mPolicy.get();
+    }
+
+    virtual InputDispatcherInterface* getDispatcher() {
+        return mDispatcher.get();
+    }
+};
+
+
+// --- FakeInputMapper ---
+
+class FakeInputMapper : public InputMapper {
+    uint32_t mSources;
+    int32_t mKeyboardType;
+    int32_t mMetaState;
+    KeyedVector<int32_t, int32_t> mKeyCodeStates;
+    KeyedVector<int32_t, int32_t> mScanCodeStates;
+    KeyedVector<int32_t, int32_t> mSwitchStates;
+    Vector<int32_t> mSupportedKeyCodes;
+    RawEvent mLastEvent;
+
+    bool mConfigureWasCalled;
+    bool mResetWasCalled;
+    bool mProcessWasCalled;
+
+public:
+    FakeInputMapper(InputDevice* device, uint32_t sources) :
+            InputMapper(device),
+            mSources(sources), mKeyboardType(AINPUT_KEYBOARD_TYPE_NONE),
+            mMetaState(0),
+            mConfigureWasCalled(false), mResetWasCalled(false), mProcessWasCalled(false) {
+    }
+
+    virtual ~FakeInputMapper() { }
+
+    void setKeyboardType(int32_t keyboardType) {
+        mKeyboardType = keyboardType;
+    }
+
+    void setMetaState(int32_t metaState) {
+        mMetaState = metaState;
+    }
+
+    void assertConfigureWasCalled() {
+        ASSERT_TRUE(mConfigureWasCalled)
+                << "Expected configure() to have been called.";
+        mConfigureWasCalled = false;
+    }
+
+    void assertResetWasCalled() {
+        ASSERT_TRUE(mResetWasCalled)
+                << "Expected reset() to have been called.";
+        mResetWasCalled = false;
+    }
+
+    void assertProcessWasCalled(RawEvent* outLastEvent = NULL) {
+        ASSERT_TRUE(mProcessWasCalled)
+                << "Expected process() to have been called.";
+        if (outLastEvent) {
+            *outLastEvent = mLastEvent;
+        }
+        mProcessWasCalled = false;
+    }
+
+    void setKeyCodeState(int32_t keyCode, int32_t state) {
+        mKeyCodeStates.replaceValueFor(keyCode, state);
+    }
+
+    void setScanCodeState(int32_t scanCode, int32_t state) {
+        mScanCodeStates.replaceValueFor(scanCode, state);
+    }
+
+    void setSwitchState(int32_t switchCode, int32_t state) {
+        mSwitchStates.replaceValueFor(switchCode, state);
+    }
+
+    void addSupportedKeyCode(int32_t keyCode) {
+        mSupportedKeyCodes.add(keyCode);
+    }
+
+private:
+    virtual uint32_t getSources() {
+        return mSources;
+    }
+
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo) {
+        InputMapper::populateDeviceInfo(deviceInfo);
+
+        if (mKeyboardType != AINPUT_KEYBOARD_TYPE_NONE) {
+            deviceInfo->setKeyboardType(mKeyboardType);
+        }
+    }
+
+    virtual void configure() {
+        mConfigureWasCalled = true;
+    }
+
+    virtual void reset() {
+        mResetWasCalled = true;
+    }
+
+    virtual void process(const RawEvent* rawEvent) {
+        mLastEvent = *rawEvent;
+        mProcessWasCalled = true;
+    }
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+        ssize_t index = mKeyCodeStates.indexOfKey(keyCode);
+        return index >= 0 ? mKeyCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
+    }
+
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+        ssize_t index = mScanCodeStates.indexOfKey(scanCode);
+        return index >= 0 ? mScanCodeStates.valueAt(index) : AKEY_STATE_UNKNOWN;
+    }
+
+    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+        ssize_t index = mSwitchStates.indexOfKey(switchCode);
+        return index >= 0 ? mSwitchStates.valueAt(index) : AKEY_STATE_UNKNOWN;
+    }
+
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags) {
+        bool result = false;
+        for (size_t i = 0; i < numCodes; i++) {
+            for (size_t j = 0; j < mSupportedKeyCodes.size(); j++) {
+                if (keyCodes[i] == mSupportedKeyCodes[j]) {
+                    outFlags[i] = 1;
+                    result = true;
+                }
+            }
+        }
+        return result;
+    }
+
+    virtual int32_t getMetaState() {
+        return mMetaState;
+    }
+};
+
+
+// --- InstrumentedInputReader ---
+
+class InstrumentedInputReader : public InputReader {
+    InputDevice* mNextDevice;
+
+public:
+    InstrumentedInputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputDispatcherInterface>& dispatcher) :
+            InputReader(eventHub, policy, dispatcher) {
+    }
+
+    virtual ~InstrumentedInputReader() {
+        if (mNextDevice) {
+            delete mNextDevice;
+        }
+    }
+
+    void setNextDevice(InputDevice* device) {
+        mNextDevice = device;
+    }
+
+protected:
+    virtual InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+        if (mNextDevice) {
+            InputDevice* device = mNextDevice;
+            mNextDevice = NULL;
+            return device;
+        }
+        return InputReader::createDevice(deviceId, name, classes);
+    }
+
+    friend class InputReaderTest;
+};
+
+
+// --- InputReaderTest ---
+
+class InputReaderTest : public testing::Test {
+protected:
+    sp<FakeInputDispatcher> mFakeDispatcher;
+    sp<FakeInputReaderPolicy> mFakePolicy;
+    sp<FakeEventHub> mFakeEventHub;
+    sp<InstrumentedInputReader> mReader;
+
+    virtual void SetUp() {
+        mFakeEventHub = new FakeEventHub();
+        mFakePolicy = new FakeInputReaderPolicy();
+        mFakeDispatcher = new FakeInputDispatcher();
+
+        mReader = new InstrumentedInputReader(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+    }
+
+    virtual void TearDown() {
+        mReader.clear();
+
+        mFakeDispatcher.clear();
+        mFakePolicy.clear();
+        mFakeEventHub.clear();
+    }
+
+    void addDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+        mFakeEventHub->addDevice(deviceId, name, classes);
+        mFakeEventHub->finishDeviceScan();
+        mReader->loopOnce();
+        mReader->loopOnce();
+        mFakeEventHub->assertQueueIsEmpty();
+    }
+
+    FakeInputMapper* addDeviceWithFakeInputMapper(int32_t deviceId,
+            const String8& name, uint32_t classes, uint32_t sources) {
+        InputDevice* device = new InputDevice(mReader.get(), deviceId, name);
+        FakeInputMapper* mapper = new FakeInputMapper(device, sources);
+        device->addMapper(mapper);
+        mReader->setNextDevice(device);
+        addDevice(deviceId, name, classes);
+        return mapper;
+    }
+};
+
+TEST_F(InputReaderTest, GetInputConfiguration_WhenNoDevices_ReturnsDefaults) {
+    InputConfiguration config;
+    mReader->getInputConfiguration(&config);
+
+    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
+    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
+    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
+}
+
+TEST_F(InputReaderTest, GetInputConfiguration_WhenAlphabeticKeyboardPresent_ReturnsQwertyKeyboard) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("keyboard"),
+            INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY));
+
+    InputConfiguration config;
+    mReader->getInputConfiguration(&config);
+
+    ASSERT_EQ(InputConfiguration::KEYBOARD_QWERTY, config.keyboard);
+    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
+    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
+}
+
+TEST_F(InputReaderTest, GetInputConfiguration_WhenTouchScreenPresent_ReturnsFingerTouchScreen) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("touchscreen"),
+            INPUT_DEVICE_CLASS_TOUCHSCREEN));
+
+    InputConfiguration config;
+    mReader->getInputConfiguration(&config);
+
+    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
+    ASSERT_EQ(InputConfiguration::NAVIGATION_NONAV, config.navigation);
+    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_FINGER, config.touchScreen);
+}
+
+TEST_F(InputReaderTest, GetInputConfiguration_WhenTrackballPresent_ReturnsTrackballNavigation) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("trackball"),
+            INPUT_DEVICE_CLASS_TRACKBALL));
+
+    InputConfiguration config;
+    mReader->getInputConfiguration(&config);
+
+    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
+    ASSERT_EQ(InputConfiguration::NAVIGATION_TRACKBALL, config.navigation);
+    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
+}
+
+TEST_F(InputReaderTest, GetInputConfiguration_WhenDPadPresent_ReturnsDPadNavigation) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(0, String8("dpad"),
+            INPUT_DEVICE_CLASS_DPAD));
+
+    InputConfiguration config;
+    mReader->getInputConfiguration(&config);
+
+    ASSERT_EQ(InputConfiguration::KEYBOARD_NOKEYS, config.keyboard);
+    ASSERT_EQ(InputConfiguration::NAVIGATION_DPAD, config.navigation);
+    ASSERT_EQ(InputConfiguration::TOUCHSCREEN_NOTOUCH, config.touchScreen);
+}
+
+TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsValid) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
+            INPUT_DEVICE_CLASS_KEYBOARD));
+
+    InputDeviceInfo info;
+    status_t result = mReader->getInputDeviceInfo(1, &info);
+
+    ASSERT_EQ(OK, result);
+    ASSERT_EQ(1, info.getId());
+    ASSERT_STREQ("keyboard", info.getName().string());
+    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC, info.getKeyboardType());
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, info.getSources());
+    ASSERT_EQ(size_t(0), info.getMotionRanges().size());
+}
+
+TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsInvalid) {
+    InputDeviceInfo info;
+    status_t result = mReader->getInputDeviceInfo(-1, &info);
+
+    ASSERT_EQ(NAME_NOT_FOUND, result);
+}
+
+TEST_F(InputReaderTest, GetInputDeviceInfo_WhenDeviceIdIsIgnored) {
+    addDevice(1, String8("ignored"), 0); // no classes so device will be ignored
+
+    InputDeviceInfo info;
+    status_t result = mReader->getInputDeviceInfo(1, &info);
+
+    ASSERT_EQ(NAME_NOT_FOUND, result);
+}
+
+TEST_F(InputReaderTest, GetInputDeviceIds) {
+    ASSERT_NO_FATAL_FAILURE(addDevice(1, String8("keyboard"),
+            INPUT_DEVICE_CLASS_KEYBOARD | INPUT_DEVICE_CLASS_ALPHAKEY));
+    ASSERT_NO_FATAL_FAILURE(addDevice(2, String8("trackball"),
+            INPUT_DEVICE_CLASS_TRACKBALL));
+
+    Vector<int32_t> ids;
+    mReader->getInputDeviceIds(ids);
+
+    ASSERT_EQ(size_t(2), ids.size());
+    ASSERT_EQ(1, ids[0]);
+    ASSERT_EQ(2, ids[1]);
+}
+
+TEST_F(InputReaderTest, GetKeyCodeState_ForwardsRequestsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
+    mapper->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(0,
+            AINPUT_SOURCE_ANY, AKEYCODE_A))
+            << "Should return unknown when the device id is >= 0 but unknown.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(1,
+            AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(1,
+            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getKeyCodeState(-1,
+            AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getKeyCodeState(-1,
+            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
+}
+
+TEST_F(InputReaderTest, GetScanCodeState_ForwardsRequestsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
+    mapper->setScanCodeState(KEY_A, AKEY_STATE_DOWN);
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(0,
+            AINPUT_SOURCE_ANY, KEY_A))
+            << "Should return unknown when the device id is >= 0 but unknown.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(1,
+            AINPUT_SOURCE_TRACKBALL, KEY_A))
+            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(1,
+            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
+            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getScanCodeState(-1,
+            AINPUT_SOURCE_TRACKBALL, KEY_A))
+            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getScanCodeState(-1,
+            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, KEY_A))
+            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
+}
+
+TEST_F(InputReaderTest, GetSwitchState_ForwardsRequestsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
+    mapper->setSwitchState(SW_LID, AKEY_STATE_DOWN);
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(0,
+            AINPUT_SOURCE_ANY, SW_LID))
+            << "Should return unknown when the device id is >= 0 but unknown.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(1,
+            AINPUT_SOURCE_TRACKBALL, SW_LID))
+            << "Should return unknown when the device id is valid but the sources are not supported by the device.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(1,
+            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
+            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mReader->getSwitchState(-1,
+            AINPUT_SOURCE_TRACKBALL, SW_LID))
+            << "Should return unknown when the device id is < 0 but the sources are not supported by any device.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mReader->getSwitchState(-1,
+            AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, SW_LID))
+            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
+}
+
+TEST_F(InputReaderTest, MarkSupportedKeyCodes_ForwardsRequestsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
+    mapper->addSupportedKeyCode(AKEYCODE_A);
+    mapper->addSupportedKeyCode(AKEYCODE_B);
+
+    const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
+    uint8_t flags[4] = { 0, 0, 0, 1 };
+
+    ASSERT_FALSE(mReader->hasKeys(0, AINPUT_SOURCE_ANY, 4, keyCodes, flags))
+            << "Should return false when device id is >= 0 but unknown.";
+    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
+
+    flags[3] = 1;
+    ASSERT_FALSE(mReader->hasKeys(1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
+            << "Should return false when device id is valid but the sources are not supported by the device.";
+    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
+
+    flags[3] = 1;
+    ASSERT_TRUE(mReader->hasKeys(1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
+            << "Should return value provided by mapper when device id is valid and the device supports some of the sources.";
+    ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
+
+    flags[3] = 1;
+    ASSERT_FALSE(mReader->hasKeys(-1, AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
+            << "Should return false when the device id is < 0 but the sources are not supported by any device.";
+    ASSERT_TRUE(!flags[0] && !flags[1] && !flags[2] && !flags[3]);
+
+    flags[3] = 1;
+    ASSERT_TRUE(mReader->hasKeys(-1, AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
+            << "Should return value provided by mapper when device id is < 0 and one of the devices supports some of the sources.";
+    ASSERT_TRUE(flags[0] && flags[1] && !flags[2] && !flags[3]);
+}
+
+TEST_F(InputReaderTest, LoopOnce_WhenDeviceScanFinished_SendsConfigurationChanged) {
+    addDevice(1, String8("ignored"), INPUT_DEVICE_CLASS_KEYBOARD);
+
+    FakeInputDispatcher::NotifyConfigurationChangedArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyConfigurationChangedWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+}
+
+TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
+    FakeInputMapper* mapper = NULL;
+    ASSERT_NO_FATAL_FAILURE(mapper = addDeviceWithFakeInputMapper(1, String8("fake"),
+            INPUT_DEVICE_CLASS_KEYBOARD, AINPUT_SOURCE_KEYBOARD));
+
+    mFakeEventHub->enqueueEvent(0, 1, EV_KEY, KEY_A, AKEYCODE_A, 1, POLICY_FLAG_WAKE);
+    mReader->loopOnce();
+    ASSERT_NO_FATAL_FAILURE(mFakeEventHub->assertQueueIsEmpty());
+
+    RawEvent event;
+    ASSERT_NO_FATAL_FAILURE(mapper->assertProcessWasCalled(&event));
+    ASSERT_EQ(0, event.when);
+    ASSERT_EQ(1, event.deviceId);
+    ASSERT_EQ(EV_KEY, event.type);
+    ASSERT_EQ(KEY_A, event.scanCode);
+    ASSERT_EQ(AKEYCODE_A, event.keyCode);
+    ASSERT_EQ(1, event.value);
+    ASSERT_EQ(POLICY_FLAG_WAKE, event.flags);
+}
+
+
+// --- InputDeviceTest ---
+
+class InputDeviceTest : public testing::Test {
+protected:
+    static const char* DEVICE_NAME;
+    static const int32_t DEVICE_ID;
+
+    sp<FakeEventHub> mFakeEventHub;
+    sp<FakeInputReaderPolicy> mFakePolicy;
+    sp<FakeInputDispatcher> mFakeDispatcher;
+    FakeInputReaderContext* mFakeContext;
+
+    InputDevice* mDevice;
+
+    virtual void SetUp() {
+        mFakeEventHub = new FakeEventHub();
+        mFakePolicy = new FakeInputReaderPolicy();
+        mFakeDispatcher = new FakeInputDispatcher();
+        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+
+        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
+    }
+
+    virtual void TearDown() {
+        delete mDevice;
+
+        delete mFakeContext;
+        mFakeDispatcher.clear();
+        mFakePolicy.clear();
+        mFakeEventHub.clear();
+    }
+};
+
+const char* InputDeviceTest::DEVICE_NAME = "device";
+const int32_t InputDeviceTest::DEVICE_ID = 1;
+
+TEST_F(InputDeviceTest, ImmutableProperties) {
+    ASSERT_EQ(DEVICE_ID, mDevice->getId());
+    ASSERT_STREQ(DEVICE_NAME, mDevice->getName());
+}
+
+TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
+    // Configuration.
+    mDevice->configure();
+
+    // Metadata.
+    ASSERT_TRUE(mDevice->isIgnored());
+    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, mDevice->getSources());
+
+    InputDeviceInfo info;
+    mDevice->getDeviceInfo(&info);
+    ASSERT_EQ(DEVICE_ID, info.getId());
+    ASSERT_STREQ(DEVICE_NAME, info.getName().string());
+    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_NONE, info.getKeyboardType());
+    ASSERT_EQ(AINPUT_SOURCE_UNKNOWN, info.getSources());
+
+    // State queries.
+    ASSERT_EQ(0, mDevice->getMetaState());
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, 0))
+            << "Ignored device should return unknown key code state.";
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 0))
+            << "Ignored device should return unknown scan code state.";
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 0))
+            << "Ignored device should return unknown switch state.";
+
+    const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
+    uint8_t flags[2] = { 0, 1 };
+    ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 2, keyCodes, flags))
+            << "Ignored device should never mark any key codes.";
+    ASSERT_EQ(0, flags[0]) << "Flag for unsupported key should be unchanged.";
+    ASSERT_EQ(1, flags[1]) << "Flag for unsupported key should be unchanged.";
+
+    // Reset.
+    mDevice->reset();
+}
+
+TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRequestsToMappers) {
+    // Configuration.
+    InputDeviceCalibration calibration;
+    calibration.addProperty(String8("key"), String8("value"));
+    mFakePolicy->addInputDeviceCalibration(String8(DEVICE_NAME), calibration);
+
+    FakeInputMapper* mapper1 = new FakeInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD);
+    mapper1->setKeyboardType(AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    mapper1->setMetaState(AMETA_ALT_ON);
+    mapper1->addSupportedKeyCode(AKEYCODE_A);
+    mapper1->addSupportedKeyCode(AKEYCODE_B);
+    mapper1->setKeyCodeState(AKEYCODE_A, AKEY_STATE_DOWN);
+    mapper1->setKeyCodeState(AKEYCODE_B, AKEY_STATE_UP);
+    mapper1->setScanCodeState(2, AKEY_STATE_DOWN);
+    mapper1->setScanCodeState(3, AKEY_STATE_UP);
+    mapper1->setSwitchState(4, AKEY_STATE_DOWN);
+    mDevice->addMapper(mapper1);
+
+    FakeInputMapper* mapper2 = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN);
+    mapper2->setMetaState(AMETA_SHIFT_ON);
+    mDevice->addMapper(mapper2);
+
+    mDevice->configure();
+
+    String8 propertyValue;
+    ASSERT_TRUE(mDevice->getCalibration().tryGetProperty(String8("key"), propertyValue))
+            << "Device should have read calibration during configuration phase.";
+    ASSERT_STREQ("value", propertyValue.string());
+
+    ASSERT_NO_FATAL_FAILURE(mapper1->assertConfigureWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mapper2->assertConfigureWasCalled());
+
+    // Metadata.
+    ASSERT_FALSE(mDevice->isIgnored());
+    ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), mDevice->getSources());
+
+    InputDeviceInfo info;
+    mDevice->getDeviceInfo(&info);
+    ASSERT_EQ(DEVICE_ID, info.getId());
+    ASSERT_STREQ(DEVICE_NAME, info.getName().string());
+    ASSERT_EQ(AINPUT_KEYBOARD_TYPE_ALPHABETIC, info.getKeyboardType());
+    ASSERT_EQ(uint32_t(AINPUT_SOURCE_KEYBOARD | AINPUT_SOURCE_TOUCHSCREEN), info.getSources());
+
+    // State queries.
+    ASSERT_EQ(AMETA_ALT_ON | AMETA_SHIFT_ON, mDevice->getMetaState())
+            << "Should query mappers and combine meta states.";
+
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return unknown key code state when source not supported.";
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getScanCodeState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return unknown scan code state when source not supported.";
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mDevice->getSwitchState(AINPUT_SOURCE_TRACKBALL, AKEYCODE_A))
+            << "Should return unknown switch state when source not supported.";
+
+    ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getKeyCodeState(AINPUT_SOURCE_KEYBOARD, AKEYCODE_A))
+            << "Should query mapper when source is supported.";
+    ASSERT_EQ(AKEY_STATE_UP, mDevice->getScanCodeState(AINPUT_SOURCE_KEYBOARD, 3))
+            << "Should query mapper when source is supported.";
+    ASSERT_EQ(AKEY_STATE_DOWN, mDevice->getSwitchState(AINPUT_SOURCE_KEYBOARD, 4))
+            << "Should query mapper when source is supported.";
+
+    const int32_t keyCodes[4] = { AKEYCODE_A, AKEYCODE_B, AKEYCODE_1, AKEYCODE_2 };
+    uint8_t flags[4] = { 0, 0, 0, 1 };
+    ASSERT_FALSE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_TRACKBALL, 4, keyCodes, flags))
+            << "Should do nothing when source is unsupported.";
+    ASSERT_EQ(0, flags[0]) << "Flag should be unchanged when source is unsupported.";
+    ASSERT_EQ(0, flags[1]) << "Flag should be unchanged when source is unsupported.";
+    ASSERT_EQ(0, flags[2]) << "Flag should be unchanged when source is unsupported.";
+    ASSERT_EQ(1, flags[3]) << "Flag should be unchanged when source is unsupported.";
+
+    ASSERT_TRUE(mDevice->markSupportedKeyCodes(AINPUT_SOURCE_KEYBOARD, 4, keyCodes, flags))
+            << "Should query mapper when source is supported.";
+    ASSERT_EQ(1, flags[0]) << "Flag for supported key should be set.";
+    ASSERT_EQ(1, flags[1]) << "Flag for supported key should be set.";
+    ASSERT_EQ(0, flags[2]) << "Flag for unsupported key should be unchanged.";
+    ASSERT_EQ(1, flags[3]) << "Flag for unsupported key should be unchanged.";
+
+    // Event handling.
+    RawEvent event;
+    mDevice->process(&event);
+
+    ASSERT_NO_FATAL_FAILURE(mapper1->assertProcessWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled());
+
+    // Reset.
+    mDevice->reset();
+
+    ASSERT_NO_FATAL_FAILURE(mapper1->assertResetWasCalled());
+    ASSERT_NO_FATAL_FAILURE(mapper2->assertResetWasCalled());
+}
+
+
+// --- InputMapperTest ---
+
+class InputMapperTest : public testing::Test {
+protected:
+    static const char* DEVICE_NAME;
+    static const int32_t DEVICE_ID;
+
+    sp<FakeEventHub> mFakeEventHub;
+    sp<FakeInputReaderPolicy> mFakePolicy;
+    sp<FakeInputDispatcher> mFakeDispatcher;
+    FakeInputReaderContext* mFakeContext;
+    InputDevice* mDevice;
+
+    virtual void SetUp() {
+        mFakeEventHub = new FakeEventHub();
+        mFakePolicy = new FakeInputReaderPolicy();
+        mFakeDispatcher = new FakeInputDispatcher();
+        mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeDispatcher);
+        mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME));
+
+        mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0);
+    }
+
+    virtual void TearDown() {
+        delete mDevice;
+        delete mFakeContext;
+        mFakeDispatcher.clear();
+        mFakePolicy.clear();
+        mFakeEventHub.clear();
+    }
+
+    void prepareCalibration(const char* key, const char* value) {
+        mFakePolicy->addInputDeviceCalibrationProperty(String8(DEVICE_NAME),
+                String8(key), String8(value));
+    }
+
+    void addMapperAndConfigure(InputMapper* mapper) {
+        mDevice->addMapper(mapper);
+        mDevice->configure();
+    }
+
+    static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
+            int32_t scanCode, int32_t keyCode, int32_t value, uint32_t flags) {
+        RawEvent event;
+        event.when = when;
+        event.deviceId = deviceId;
+        event.type = type;
+        event.scanCode = scanCode;
+        event.keyCode = keyCode;
+        event.value = value;
+        event.flags = flags;
+        mapper->process(&event);
+    }
+
+    static void assertMotionRange(const InputDeviceInfo& info,
+            int32_t rangeType, float min, float max, float flat, float fuzz) {
+        const InputDeviceInfo::MotionRange* range = info.getMotionRange(rangeType);
+        ASSERT_TRUE(range != NULL) << "Range: " << rangeType;
+        ASSERT_NEAR(min, range->min, EPSILON) << "Range: " << rangeType;
+        ASSERT_NEAR(max, range->max, EPSILON) << "Range: " << rangeType;
+        ASSERT_NEAR(flat, range->flat, EPSILON) << "Range: " << rangeType;
+        ASSERT_NEAR(fuzz, range->fuzz, EPSILON) << "Range: " << rangeType;
+    }
+
+    static void assertPointerCoords(const PointerCoords& coords,
+            float x, float y, float pressure, float size,
+            float touchMajor, float touchMinor, float toolMajor, float toolMinor,
+            float orientation) {
+        ASSERT_NEAR(x, coords.x, 1);
+        ASSERT_NEAR(y, coords.y, 1);
+        ASSERT_NEAR(pressure, coords.pressure, EPSILON);
+        ASSERT_NEAR(size, coords.size, EPSILON);
+        ASSERT_NEAR(touchMajor, coords.touchMajor, 1);
+        ASSERT_NEAR(touchMinor, coords.touchMinor, 1);
+        ASSERT_NEAR(toolMajor, coords.toolMajor, 1);
+        ASSERT_NEAR(toolMinor, coords.toolMinor, 1);
+        ASSERT_NEAR(orientation, coords.orientation, EPSILON);
+    }
+};
+
+const char* InputMapperTest::DEVICE_NAME = "device";
+const int32_t InputMapperTest::DEVICE_ID = 1;
+
+
+// --- SwitchInputMapperTest ---
+
+class SwitchInputMapperTest : public InputMapperTest {
+protected:
+};
+
+TEST_F(SwitchInputMapperTest, GetSources) {
+    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(uint32_t(0), mapper->getSources());
+}
+
+TEST_F(SwitchInputMapperTest, GetSwitchState) {
+    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
+    addMapperAndConfigure(mapper);
+
+    mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 1);
+    ASSERT_EQ(1, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
+
+    mFakeEventHub->setSwitchState(DEVICE_ID, SW_LID, 0);
+    ASSERT_EQ(0, mapper->getSwitchState(AINPUT_SOURCE_ANY, SW_LID));
+}
+
+TEST_F(SwitchInputMapperTest, Process) {
+    SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
+    addMapperAndConfigure(mapper);
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SW, SW_LID, 0, 1, 0);
+
+    FakeInputDispatcher::NotifySwitchArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifySwitchWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.when);
+    ASSERT_EQ(SW_LID, args.switchCode);
+    ASSERT_EQ(1, args.switchValue);
+    ASSERT_EQ(uint32_t(0), args.policyFlags);
+}
+
+
+// --- KeyboardInputMapperTest ---
+
+class KeyboardInputMapperTest : public InputMapperTest {
+protected:
+    void testDPadKeyRotation(KeyboardInputMapper* mapper,
+            int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode);
+};
+
+void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper,
+        int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) {
+    FakeInputDispatcher::NotifyKeyArgs args;
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
+    ASSERT_EQ(originalScanCode, args.scanCode);
+    ASSERT_EQ(rotatedKeyCode, args.keyCode);
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, originalScanCode, originalKeyCode, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(originalScanCode, args.scanCode);
+    ASSERT_EQ(rotatedKeyCode, args.keyCode);
+}
+
+
+TEST_F(KeyboardInputMapperTest, GetSources) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, mapper->getSources());
+}
+
+TEST_F(KeyboardInputMapperTest, Process_SimpleKeyPress) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    // Key down.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
+    FakeInputDispatcher::NotifyKeyArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
+    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
+    ASSERT_EQ(KEY_HOME, args.scanCode);
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
+    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+
+    // Key up.
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
+            EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
+    ASSERT_EQ(KEY_HOME, args.scanCode);
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
+    ASSERT_EQ(POLICY_FLAG_WAKE, args.policyFlags);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+}
+
+TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreNotDown_DoesNotSynthesizeKeyUp) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    // Key down.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_HOME, AKEYCODE_HOME, 1, POLICY_FLAG_WAKE);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Key up.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_HOME, AKEYCODE_HOME, 0, POLICY_FLAG_WAKE);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Reset.  Since no keys still down, should not synthesize any key ups.
+    mapper->reset();
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+}
+
+TEST_F(KeyboardInputMapperTest, Reset_WhenKeysAreDown_SynthesizesKeyUps) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    // Metakey down.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Key down.
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
+            EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Reset.  Since two keys are still down, should synthesize two key ups in reverse order.
+    mapper->reset();
+
+    FakeInputDispatcher::NotifyKeyArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(AKEYCODE_A, args.keyCode);
+    ASSERT_EQ(KEY_A, args.scanCode);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
+    ASSERT_EQ(uint32_t(0), args.policyFlags);
+    ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(AKEYCODE_SHIFT_LEFT, args.keyCode);
+    ASSERT_EQ(KEY_LEFTSHIFT, args.scanCode);
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM, args.flags);
+    ASSERT_EQ(uint32_t(0), args.policyFlags);
+    ASSERT_EQ(ARBITRARY_TIME + 1, args.downTime);
+
+    // And that's it.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+}
+
+TEST_F(KeyboardInputMapperTest, Process_ShouldUpdateMetaState) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    // Initial metastate.
+    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
+
+    // Metakey down.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID,
+            EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 1, 0);
+    FakeInputDispatcher::NotifyKeyArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
+    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
+
+    // Key down.
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID,
+            EV_KEY, KEY_A, AKEYCODE_A, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
+
+    // Key up.
+    process(mapper, ARBITRARY_TIME + 2, DEVICE_ID,
+            EV_KEY, KEY_A, AKEYCODE_A, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, mapper->getMetaState());
+
+    // Metakey up.
+    process(mapper, ARBITRARY_TIME + 3, DEVICE_ID,
+            EV_KEY, KEY_LEFTSHIFT, AKEYCODE_SHIFT_LEFT, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AMETA_NONE, args.metaState);
+    ASSERT_EQ(AMETA_NONE, mapper->getMetaState());
+    ASSERT_NO_FATAL_FAILURE(mFakeContext->assertUpdateGlobalMetaStateWasCalled());
+}
+
+TEST_F(KeyboardInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotateDPad) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
+}
+
+TEST_F(KeyboardInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateDPad) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, DISPLAY_ID,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_0);
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT));
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_90);
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN));
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_180);
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT));
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_270);
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT));
+    ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper,
+            KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP));
+
+    // Special case: if orientation changes while key is down, we still emit the same keycode
+    // in the key up as we did in the key down.
+    FakeInputDispatcher::NotifyKeyArgs args;
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_270);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
+    ASSERT_EQ(KEY_UP, args.scanCode);
+    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_180);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, AKEYCODE_DPAD_UP, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(KEY_UP, args.scanCode);
+    ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
+}
+
+TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 1);
+    ASSERT_EQ(1, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
+
+    mFakeEventHub->setKeyCodeState(DEVICE_ID, AKEYCODE_A, 0);
+    ASSERT_EQ(0, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
+}
+
+TEST_F(KeyboardInputMapperTest, GetScanCodeState) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 1);
+    ASSERT_EQ(1, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
+
+    mFakeEventHub->setScanCodeState(DEVICE_ID, KEY_A, 0);
+    ASSERT_EQ(0, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
+}
+
+TEST_F(KeyboardInputMapperTest, MarkSupportedKeyCodes) {
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, -1,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+
+    mFakeEventHub->addKey(DEVICE_ID, KEY_A, AKEYCODE_A, 0);
+
+    const int32_t keyCodes[2] = { AKEYCODE_A, AKEYCODE_B };
+    uint8_t flags[2] = { 0, 0 };
+    ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 1, keyCodes, flags));
+    ASSERT_TRUE(flags[0]);
+    ASSERT_FALSE(flags[1]);
+}
+
+
+// --- TrackballInputMapperTest ---
+
+class TrackballInputMapperTest : public InputMapperTest {
+protected:
+    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD;
+
+    void testMotionRotation(TrackballInputMapper* mapper,
+            int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY);
+};
+
+const int32_t TrackballInputMapperTest::TRACKBALL_MOVEMENT_THRESHOLD = 6;
+
+void TrackballInputMapperTest::testMotionRotation(TrackballInputMapper* mapper,
+        int32_t originalX, int32_t originalY, int32_t rotatedX, int32_t rotatedY) {
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, originalX, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, originalY, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            float(rotatedX) / TRACKBALL_MOVEMENT_THRESHOLD,
+            float(rotatedY) / TRACKBALL_MOVEMENT_THRESHOLD,
+            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+}
+
+TEST_F(TrackballInputMapperTest, GetSources) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, mapper->getSources());
+}
+
+TEST_F(TrackballInputMapperTest, PopulateDeviceInfo) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    InputDeviceInfo info;
+    mapper->populateDeviceInfo(&info);
+
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_X,
+            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
+    ASSERT_NO_FATAL_FAILURE(assertMotionRange(info, AINPUT_MOTION_RANGE_Y,
+            -1.0f, 1.0f, 0.0f, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD));
+}
+
+TEST_F(TrackballInputMapperTest, Process_ShouldSetAllFieldsAndIncludeGlobalMetaState) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Button press.
+    // Mostly testing non x/y behavior here so we don't need to check again elsewhere.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
+    ASSERT_EQ(uint32_t(0), args.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+    ASSERT_EQ(0, args.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(0, args.edgeFlags);
+    ASSERT_EQ(uint32_t(1), args.pointerCount);
+    ASSERT_EQ(0, args.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
+    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+
+    // Button release.  Should have same down time.
+    process(mapper, ARBITRARY_TIME + 1, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME + 1, args.eventTime);
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TRACKBALL, args.source);
+    ASSERT_EQ(uint32_t(0), args.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(0, args.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(0, args.edgeFlags);
+    ASSERT_EQ(uint32_t(1), args.pointerCount);
+    ASSERT_EQ(0, args.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.xPrecision);
+    ASSERT_EQ(TRACKBALL_MOVEMENT_THRESHOLD, args.yPrecision);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+}
+
+TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentXYUpdates) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Motion in X but not Y.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            1.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    // Motion in Y but not X.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+    ASSERT_NEAR(0.0f, args.pointerCoords[0].x, EPSILON);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+}
+
+TEST_F(TrackballInputMapperTest, Process_ShouldHandleIndependentButtonUpdates) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Button press without following sync.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    // Button release without following sync.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+}
+
+TEST_F(TrackballInputMapperTest, Process_ShouldHandleCombinedXYAndButtonUpdates) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Combined X, Y and Button.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 1, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, -2, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            1.0f / TRACKBALL_MOVEMENT_THRESHOLD, -2.0f / TRACKBALL_MOVEMENT_THRESHOLD,
+            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    // Move X, Y a bit while pressed.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_X, 0, 2, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_REL, REL_Y, 0, 1, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            2.0f / TRACKBALL_MOVEMENT_THRESHOLD, 1.0f / TRACKBALL_MOVEMENT_THRESHOLD,
+            1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+
+    // Release Button.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+}
+
+TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsNotDown_ShouldNotSynthesizeButtonUp) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Button press.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+
+    // Button release.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 0, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+
+    // Reset.  Should not synthesize button up since button is not pressed.
+    mapper->reset();
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(TrackballInputMapperTest, Reset_WhenButtonIsDown_ShouldSynthesizeButtonUp) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Button press.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_MOUSE, 0, 1, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+
+    // Reset.  Should synthesize button up.
+    mapper->reset();
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, args.action);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f));
+}
+
+TEST_F(TrackballInputMapperTest, Process_WhenNotAttachedToDisplay_ShouldNotRotateMotions) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, -1);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
+}
+
+TEST_F(TrackballInputMapperTest, Process_WhenAttachedToDisplay_ShouldRotateMotions) {
+    TrackballInputMapper* mapper = new TrackballInputMapper(mDevice, DISPLAY_ID);
+    addMapperAndConfigure(mapper);
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_0);
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1,  1));
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_90);
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1,  1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1, -1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1,  1));
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_180);
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1, -1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1,  1, -1));
+
+    mFakePolicy->setDisplayInfo(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT,
+            InputReaderPolicyInterface::ROTATION_270);
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0,  1, -1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  1, -1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1,  0,  0,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  1, -1,  1,  1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper,  0, -1,  1,  0));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1, -1,  1, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  0,  0, -1));
+    ASSERT_NO_FATAL_FAILURE(testMotionRotation(mapper, -1,  1, -1, -1));
+}
+
+
+// --- TouchInputMapperTest ---
+
+class TouchInputMapperTest : public InputMapperTest {
+protected:
+    static const int32_t RAW_X_MIN;
+    static const int32_t RAW_X_MAX;
+    static const int32_t RAW_Y_MIN;
+    static const int32_t RAW_Y_MAX;
+    static const int32_t RAW_TOUCH_MIN;
+    static const int32_t RAW_TOUCH_MAX;
+    static const int32_t RAW_TOOL_MIN;
+    static const int32_t RAW_TOOL_MAX;
+    static const int32_t RAW_PRESSURE_MIN;
+    static const int32_t RAW_PRESSURE_MAX;
+    static const int32_t RAW_ORIENTATION_MIN;
+    static const int32_t RAW_ORIENTATION_MAX;
+    static const int32_t RAW_ID_MIN;
+    static const int32_t RAW_ID_MAX;
+    static const float X_PRECISION;
+    static const float Y_PRECISION;
+
+    static const VirtualKeyDefinition VIRTUAL_KEYS[2];
+
+    enum Axes {
+        POSITION = 1 << 0,
+        TOUCH = 1 << 1,
+        TOOL = 1 << 2,
+        PRESSURE = 1 << 3,
+        ORIENTATION = 1 << 4,
+        MINOR = 1 << 5,
+        ID = 1 << 6,
+    };
+
+    void prepareDisplay(int32_t orientation);
+    void prepareVirtualKeys();
+    int32_t toRawX(float displayX);
+    int32_t toRawY(float displayY);
+    float toDisplayX(int32_t rawX);
+    float toDisplayY(int32_t rawY);
+};
+
+const int32_t TouchInputMapperTest::RAW_X_MIN = 25;
+const int32_t TouchInputMapperTest::RAW_X_MAX = 1020;
+const int32_t TouchInputMapperTest::RAW_Y_MIN = 30;
+const int32_t TouchInputMapperTest::RAW_Y_MAX = 1010;
+const int32_t TouchInputMapperTest::RAW_TOUCH_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_TOUCH_MAX = 31;
+const int32_t TouchInputMapperTest::RAW_TOOL_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_TOOL_MAX = 15;
+const int32_t TouchInputMapperTest::RAW_PRESSURE_MIN = RAW_TOUCH_MIN;
+const int32_t TouchInputMapperTest::RAW_PRESSURE_MAX = RAW_TOUCH_MAX;
+const int32_t TouchInputMapperTest::RAW_ORIENTATION_MIN = -7;
+const int32_t TouchInputMapperTest::RAW_ORIENTATION_MAX = 7;
+const int32_t TouchInputMapperTest::RAW_ID_MIN = 0;
+const int32_t TouchInputMapperTest::RAW_ID_MAX = 9;
+const float TouchInputMapperTest::X_PRECISION = float(RAW_X_MAX - RAW_X_MIN) / DISPLAY_WIDTH;
+const float TouchInputMapperTest::Y_PRECISION = float(RAW_Y_MAX - RAW_Y_MIN) / DISPLAY_HEIGHT;
+
+const VirtualKeyDefinition TouchInputMapperTest::VIRTUAL_KEYS[2] = {
+        { KEY_HOME, 60, DISPLAY_HEIGHT + 15, 20, 20 },
+        { KEY_MENU, DISPLAY_HEIGHT - 60, DISPLAY_WIDTH + 15, 20, 20 },
+};
+
+void TouchInputMapperTest::prepareDisplay(int32_t orientation) {
+    mFakePolicy->setDisplayInfo(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, orientation);
+}
+
+void TouchInputMapperTest::prepareVirtualKeys() {
+    mFakePolicy->addVirtualKeyDefinition(String8(DEVICE_NAME), VIRTUAL_KEYS[0]);
+    mFakePolicy->addVirtualKeyDefinition(String8(DEVICE_NAME), VIRTUAL_KEYS[1]);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_HOME, AKEYCODE_HOME, POLICY_FLAG_WAKE);
+    mFakeEventHub->addKey(DEVICE_ID, KEY_MENU, AKEYCODE_MENU, POLICY_FLAG_WAKE);
+}
+
+int32_t TouchInputMapperTest::toRawX(float displayX) {
+    return int32_t(displayX * (RAW_X_MAX - RAW_X_MIN) / DISPLAY_WIDTH + RAW_X_MIN);
+}
+
+int32_t TouchInputMapperTest::toRawY(float displayY) {
+    return int32_t(displayY * (RAW_Y_MAX - RAW_Y_MIN) / DISPLAY_HEIGHT + RAW_Y_MIN);
+}
+
+float TouchInputMapperTest::toDisplayX(int32_t rawX) {
+    return float(rawX - RAW_X_MIN) * DISPLAY_WIDTH / (RAW_X_MAX - RAW_X_MIN);
+}
+
+float TouchInputMapperTest::toDisplayY(int32_t rawY) {
+    return float(rawY - RAW_Y_MIN) * DISPLAY_HEIGHT / (RAW_Y_MAX - RAW_Y_MIN);
+}
+
+
+// --- SingleTouchInputMapperTest ---
+
+class SingleTouchInputMapperTest : public TouchInputMapperTest {
+protected:
+    void prepareAxes(int axes);
+
+    void processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
+    void processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y);
+    void processUp(SingleTouchInputMapper* mappery);
+    void processPressure(SingleTouchInputMapper* mapper, int32_t pressure);
+    void processToolMajor(SingleTouchInputMapper* mapper, int32_t toolMajor);
+    void processSync(SingleTouchInputMapper* mapper);
+};
+
+void SingleTouchInputMapperTest::prepareAxes(int axes) {
+    if (axes & POSITION) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+    }
+    if (axes & PRESSURE) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_PRESSURE, RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+    }
+    if (axes & TOOL) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_TOOL_WIDTH, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+    }
+}
+
+void SingleTouchInputMapperTest::processDown(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0, 1, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, 0, x, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, 0, y, 0);
+}
+
+void SingleTouchInputMapperTest::processMove(SingleTouchInputMapper* mapper, int32_t x, int32_t y) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_X, 0, x, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_Y, 0, y, 0);
+}
+
+void SingleTouchInputMapperTest::processUp(SingleTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, BTN_TOUCH, 0, 0, 0);
+}
+
+void SingleTouchInputMapperTest::processPressure(
+        SingleTouchInputMapper* mapper, int32_t pressure) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_PRESSURE, 0, pressure, 0);
+}
+
+void SingleTouchInputMapperTest::processToolMajor(
+        SingleTouchInputMapper* mapper, int32_t toolMajor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_TOOL_WIDTH, 0, toolMajor, 0);
+}
+
+void SingleTouchInputMapperTest::processSync(SingleTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+}
+
+
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenNotAttachedToADisplay_ReturnsTouchPad) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, -1);
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHPAD, mapper->getSources());
+}
+
+TEST_F(SingleTouchInputMapperTest, GetSources_WhenAttachedToADisplay_ReturnsTouchScreen) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, mapper->getSources());
+}
+
+TEST_F(SingleTouchInputMapperTest, GetKeyCodeState) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    // Unknown key.
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_A));
+
+    // Virtual key is down.
+    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
+    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
+    processDown(mapper, x, y);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
+
+    // Virtual key is up.
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    ASSERT_EQ(AKEY_STATE_UP, mapper->getKeyCodeState(AINPUT_SOURCE_ANY, AKEYCODE_HOME));
+}
+
+TEST_F(SingleTouchInputMapperTest, GetScanCodeState) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    // Unknown key.
+    ASSERT_EQ(AKEY_STATE_UNKNOWN, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_A));
+
+    // Virtual key is down.
+    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
+    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
+    processDown(mapper, x, y);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    ASSERT_EQ(AKEY_STATE_VIRTUAL, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
+
+    // Virtual key is up.
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    ASSERT_EQ(AKEY_STATE_UP, mapper->getScanCodeState(AINPUT_SOURCE_ANY, KEY_HOME));
+}
+
+TEST_F(SingleTouchInputMapperTest, MarkSupportedKeyCodes) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    const int32_t keys[2] = { AKEYCODE_HOME, AKEYCODE_A };
+    uint8_t flags[2] = { 0, 0 };
+    ASSERT_TRUE(mapper->markSupportedKeyCodes(AINPUT_SOURCE_ANY, 2, keys, flags));
+    ASSERT_TRUE(flags[0]);
+    ASSERT_FALSE(flags[1]);
+}
+
+TEST_F(SingleTouchInputMapperTest, Reset_WhenVirtualKeysAreDown_SendsUp) {
+    // Note: Ideally we should send cancels but the implementation is more straightforward
+    // with up and this will only happen if a device is forcibly removed.
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    // Press virtual key.
+    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
+    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
+    processDown(mapper, x, y);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Reset.  Since key is down, synthesize key up.
+    mapper->reset();
+
+    FakeInputDispatcher::NotifyKeyArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    //ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
+    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
+    ASSERT_EQ(KEY_HOME, args.scanCode);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+}
+
+TEST_F(SingleTouchInputMapperTest, Reset_WhenNothingIsPressed_NothingMuchHappens) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    // Press virtual key.
+    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
+    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
+    processDown(mapper, x, y);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Release virtual key.
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled());
+
+    // Reset.  Since no key is down, nothing happens.
+    mapper->reset();
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndReleasedNormally_SendsKeyDownAndKeyUp) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyKeyArgs args;
+
+    // Press virtual key.
+    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
+    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
+    processDown(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
+    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
+    ASSERT_EQ(KEY_HOME, args.scanCode);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+
+    // Release virtual key.
+    processUp(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(ARBITRARY_TIME, args.eventTime);
+    ASSERT_EQ(DEVICE_ID, args.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, args.source);
+    ASSERT_EQ(POLICY_FLAG_VIRTUAL, args.policyFlags);
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, args.flags);
+    ASSERT_EQ(AKEYCODE_HOME, args.keyCode);
+    ASSERT_EQ(KEY_HOME, args.scanCode);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, args.metaState);
+    ASSERT_EQ(ARBITRARY_TIME, args.downTime);
+
+    // Should not have sent any motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenVirtualKeyIsPressedAndMovedOutOfBounds_SendsKeyDownAndKeyCancel) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyKeyArgs keyArgs;
+
+    // Press virtual key.
+    int32_t x = toRawX(VIRTUAL_KEYS[0].centerX);
+    int32_t y = toRawY(VIRTUAL_KEYS[0].centerY);
+    processDown(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
+    ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
+    ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, keyArgs.action);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY, keyArgs.flags);
+    ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
+    ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
+    ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
+
+    // Move out of bounds.  This should generate a cancel and a pointer down since we moved
+    // into the display area.
+    y -= 100;
+    processMove(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasCalled(&keyArgs));
+    ASSERT_EQ(ARBITRARY_TIME, keyArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, keyArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_KEYBOARD, keyArgs.source);
+    ASSERT_EQ(POLICY_FLAG_VIRTUAL, keyArgs.policyFlags);
+    ASSERT_EQ(AKEY_EVENT_ACTION_UP, keyArgs.action);
+    ASSERT_EQ(AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+            | AKEY_EVENT_FLAG_CANCELED, keyArgs.flags);
+    ASSERT_EQ(AKEYCODE_HOME, keyArgs.keyCode);
+    ASSERT_EQ(KEY_HOME, keyArgs.scanCode);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, keyArgs.metaState);
+    ASSERT_EQ(ARBITRARY_TIME, keyArgs.downTime);
+
+    FakeInputDispatcher::NotifyMotionArgs motionArgs;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Keep moving out of bounds.  Should generate a pointer move.
+    y -= 50;
+    processMove(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Release out of bounds.  Should generate a pointer up.
+    processUp(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_WhenTouchStartsOutsideDisplayAndMovesIn_SendsDownAsTouchEntersDisplay) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyMotionArgs motionArgs;
+
+    // Initially go down out of bounds.
+    int32_t x = -10;
+    int32_t y = -10;
+    processDown(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+
+    // Move into the display area.  Should generate a pointer down.
+    x = 50;
+    y = 75;
+    processMove(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Release.  Should generate a pointer up.
+    processUp(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_NormalSingleTouchGesture) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyMotionArgs motionArgs;
+
+    // Down.
+    int32_t x = 100;
+    int32_t y = 125;
+    processDown(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Move.
+    x += 50;
+    y += 75;
+    processMove(mapper, x, y);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Up.
+    processUp(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x), toDisplayY(y), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_Rotation) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareAxes(POSITION);
+    addMapperAndConfigure(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+
+    // Rotation 0.
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    processDown(mapper, toRawX(50), toRawY(75));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(50, args.pointerCoords[0].x, 1);
+    ASSERT_NEAR(75, args.pointerCoords[0].y, 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+
+    // Rotation 90.
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_90);
+    processDown(mapper, toRawX(50), toRawY(75));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(75, args.pointerCoords[0].x, 1);
+    ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].y, 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+
+    // Rotation 180.
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_180);
+    processDown(mapper, toRawX(50), toRawY(75));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(DISPLAY_WIDTH - 50, args.pointerCoords[0].x, 1);
+    ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].y, 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+
+    // Rotation 270.
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_270);
+    processDown(mapper, toRawX(50), toRawY(75));
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NEAR(DISPLAY_HEIGHT - 75, args.pointerCoords[0].x, 1);
+    ASSERT_NEAR(50, args.pointerCoords[0].y, 1);
+
+    processUp(mapper);
+    processSync(mapper);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled());
+}
+
+TEST_F(SingleTouchInputMapperTest, Process_AllAxes_DefaultCalibration) {
+    SingleTouchInputMapper* mapper = new SingleTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION | PRESSURE | TOOL);
+    addMapperAndConfigure(mapper);
+
+    // These calculations are based on the input device calibration documentation.
+    int32_t rawX = 100;
+    int32_t rawY = 200;
+    int32_t rawPressure = 10;
+    int32_t rawToolMajor = 12;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
+    float size = float(rawToolMajor) / RAW_TOOL_MAX;
+    float tool = min(DISPLAY_WIDTH, DISPLAY_HEIGHT) * size;
+    float touch = min(tool * pressure, tool);
+
+    processDown(mapper, rawX, rawY);
+    processPressure(mapper, rawPressure);
+    processToolMajor(mapper, rawToolMajor);
+    processSync(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, touch, touch, tool, tool, 0));
+}
+
+
+// --- MultiTouchInputMapperTest ---
+
+class MultiTouchInputMapperTest : public TouchInputMapperTest {
+protected:
+    void prepareAxes(int axes);
+
+    void processPosition(MultiTouchInputMapper* mapper, int32_t x, int32_t y);
+    void processTouchMajor(MultiTouchInputMapper* mapper, int32_t touchMajor);
+    void processTouchMinor(MultiTouchInputMapper* mapper, int32_t touchMinor);
+    void processToolMajor(MultiTouchInputMapper* mapper, int32_t toolMajor);
+    void processToolMinor(MultiTouchInputMapper* mapper, int32_t toolMinor);
+    void processOrientation(MultiTouchInputMapper* mapper, int32_t orientation);
+    void processPressure(MultiTouchInputMapper* mapper, int32_t pressure);
+    void processId(MultiTouchInputMapper* mapper, int32_t id);
+    void processMTSync(MultiTouchInputMapper* mapper);
+    void processSync(MultiTouchInputMapper* mapper);
+};
+
+void MultiTouchInputMapperTest::prepareAxes(int axes) {
+    if (axes & POSITION) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_POSITION_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
+    }
+    if (axes & TOUCH) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MAJOR, RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+        if (axes & MINOR) {
+            mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TOUCH_MINOR,
+                    RAW_TOUCH_MIN, RAW_TOUCH_MAX, 0, 0);
+        }
+    }
+    if (axes & TOOL) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MAJOR, RAW_TOOL_MIN, RAW_TOOL_MAX, 0, 0);
+        if (axes & MINOR) {
+            mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_WIDTH_MINOR,
+                    RAW_TOOL_MAX, RAW_TOOL_MAX, 0, 0);
+        }
+    }
+    if (axes & ORIENTATION) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_ORIENTATION,
+                RAW_ORIENTATION_MIN, RAW_ORIENTATION_MAX, 0, 0);
+    }
+    if (axes & PRESSURE) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_PRESSURE,
+                RAW_PRESSURE_MIN, RAW_PRESSURE_MAX, 0, 0);
+    }
+    if (axes & ID) {
+        mFakeEventHub->addAxis(DEVICE_ID, ABS_MT_TRACKING_ID,
+                RAW_ID_MIN, RAW_ID_MAX, 0, 0);
+    }
+}
+
+void MultiTouchInputMapperTest::processPosition(
+        MultiTouchInputMapper* mapper, int32_t x, int32_t y) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_X, 0, x, 0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_POSITION_Y, 0, y, 0);
+}
+
+void MultiTouchInputMapperTest::processTouchMajor(
+        MultiTouchInputMapper* mapper, int32_t touchMajor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MAJOR, 0, touchMajor, 0);
+}
+
+void MultiTouchInputMapperTest::processTouchMinor(
+        MultiTouchInputMapper* mapper, int32_t touchMinor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TOUCH_MINOR, 0, touchMinor, 0);
+}
+
+void MultiTouchInputMapperTest::processToolMajor(
+        MultiTouchInputMapper* mapper, int32_t toolMajor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MAJOR, 0, toolMajor, 0);
+}
+
+void MultiTouchInputMapperTest::processToolMinor(
+        MultiTouchInputMapper* mapper, int32_t toolMinor) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_WIDTH_MINOR, 0, toolMinor, 0);
+}
+
+void MultiTouchInputMapperTest::processOrientation(
+        MultiTouchInputMapper* mapper, int32_t orientation) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_ORIENTATION, 0, orientation, 0);
+}
+
+void MultiTouchInputMapperTest::processPressure(
+        MultiTouchInputMapper* mapper, int32_t pressure) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_PRESSURE, 0, pressure, 0);
+}
+
+void MultiTouchInputMapperTest::processId(
+        MultiTouchInputMapper* mapper, int32_t id) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_ABS, ABS_MT_TRACKING_ID, 0, id, 0);
+}
+
+void MultiTouchInputMapperTest::processMTSync(MultiTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_MT_REPORT, 0, 0, 0);
+}
+
+void MultiTouchInputMapperTest::processSync(MultiTouchInputMapper* mapper) {
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_SYN, SYN_REPORT, 0, 0, 0);
+}
+
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithoutTrackingIds) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyMotionArgs motionArgs;
+
+    // Two fingers down at once.
+    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+    processPosition(mapper, x1, y1);
+    processMTSync(mapper);
+    processPosition(mapper, x2, y2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_EQ(1, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Move.
+    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
+    processPosition(mapper, x1, y1);
+    processMTSync(mapper);
+    processPosition(mapper, x2, y2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_EQ(1, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // First finger up.
+    x2 += 15; y2 -= 20;
+    processPosition(mapper, x2, y2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_EQ(1, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Move.
+    x2 += 20; y2 -= 25;
+    processPosition(mapper, x2, y2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // New finger down.
+    int32_t x3 = 700, y3 = 300;
+    processPosition(mapper, x2, y2);
+    processMTSync(mapper);
+    processPosition(mapper, x3, y3);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_EQ(1, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Second finger up.
+    x3 += 30; y3 -= 20;
+    processPosition(mapper, x3, y3);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_EQ(1, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Last finger up.
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.eventTime);
+    ASSERT_EQ(DEVICE_ID, motionArgs.deviceId);
+    ASSERT_EQ(AINPUT_SOURCE_TOUCHSCREEN, motionArgs.source);
+    ASSERT_EQ(uint32_t(0), motionArgs.policyFlags);
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(0, motionArgs.flags);
+    ASSERT_EQ(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON, motionArgs.metaState);
+    ASSERT_EQ(0, motionArgs.edgeFlags);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(0, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NEAR(X_PRECISION, motionArgs.xPrecision, EPSILON);
+    ASSERT_NEAR(Y_PRECISION, motionArgs.yPrecision, EPSILON);
+    ASSERT_EQ(ARBITRARY_TIME, motionArgs.downTime);
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_NormalMultiTouchGesture_WithTrackingIds) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION | ID);
+    prepareVirtualKeys();
+    addMapperAndConfigure(mapper);
+
+    mFakeContext->setGlobalMetaState(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_ON);
+
+    FakeInputDispatcher::NotifyMotionArgs motionArgs;
+
+    // Two fingers down at once.
+    int32_t x1 = 100, y1 = 125, x2 = 300, y2 = 500;
+    processPosition(mapper, x1, y1);
+    processId(mapper, 1);
+    processMTSync(mapper);
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerIds[0]);
+    ASSERT_EQ(2, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+
+    // Move.
+    x1 += 10; y1 += 15; x2 += 5; y2 -= 10;
+    processPosition(mapper, x1, y1);
+    processId(mapper, 1);
+    processMTSync(mapper);
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerIds[0]);
+    ASSERT_EQ(2, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+
+    // First finger up.
+    x2 += 15; y2 -= 20;
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(1, motionArgs.pointerIds[0]);
+    ASSERT_EQ(2, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x1), toDisplayY(y1), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(2, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+
+    // Move.
+    x2 += 20; y2 -= 25;
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(2, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+
+    // New finger down.
+    int32_t x3 = 700, y3 = 300;
+    processPosition(mapper, x2, y2);
+    processId(mapper, 2);
+    processMTSync(mapper);
+    processPosition(mapper, x3, y3);
+    processId(mapper, 3);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(2, motionArgs.pointerIds[0]);
+    ASSERT_EQ(3, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+
+    // Second finger up.
+    x3 += 30; y3 -= 20;
+    processPosition(mapper, x3, y3);
+    processId(mapper, 3);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            motionArgs.action);
+    ASSERT_EQ(size_t(2), motionArgs.pointerCount);
+    ASSERT_EQ(2, motionArgs.pointerIds[0]);
+    ASSERT_EQ(3, motionArgs.pointerIds[1]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x2), toDisplayY(y2), 1, 0, 0, 0, 0, 0, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[1],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_MOVE, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(3, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+
+    // Last finger up.
+    processMTSync(mapper);
+    processSync(mapper);
+
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&motionArgs));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_UP, motionArgs.action);
+    ASSERT_EQ(size_t(1), motionArgs.pointerCount);
+    ASSERT_EQ(3, motionArgs.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(motionArgs.pointerCoords[0],
+            toDisplayX(x3), toDisplayY(y3), 1, 0, 0, 0, 0, 0, 0));
+
+    // Should not have sent any more keys or motions.
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyKeyWasNotCalled());
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasNotCalled());
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_AllAxes_WithDefaultCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL | PRESSURE | ORIENTATION | ID | MINOR);
+    addMapperAndConfigure(mapper);
+
+    // These calculations are based on the input device calibration documentation.
+    int32_t rawX = 100;
+    int32_t rawY = 200;
+    int32_t rawTouchMajor = 7;
+    int32_t rawTouchMinor = 6;
+    int32_t rawToolMajor = 9;
+    int32_t rawToolMinor = 8;
+    int32_t rawPressure = 11;
+    int32_t rawOrientation = 3;
+    int32_t id = 5;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float pressure = float(rawPressure) / RAW_PRESSURE_MAX;
+    float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX;
+    float toolMajor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMajor / RAW_TOOL_MAX;
+    float toolMinor = float(min(DISPLAY_WIDTH, DISPLAY_HEIGHT)) * rawToolMinor / RAW_TOOL_MAX;
+    float touchMajor = min(toolMajor * pressure, toolMajor);
+    float touchMinor = min(toolMinor * pressure, toolMinor);
+    float orientation = float(rawOrientation) / RAW_ORIENTATION_MAX * M_PI_2;
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processTouchMinor(mapper, rawTouchMinor);
+    processToolMajor(mapper, rawToolMajor);
+    processToolMinor(mapper, rawToolMinor);
+    processPressure(mapper, rawPressure);
+    processOrientation(mapper, rawOrientation);
+    processId(mapper, id);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(id, args.pointerIds[0]);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, orientation));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_TouchAndToolAxes_GeometricCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL | MINOR);
+    prepareCalibration("touch.touchSize.calibration", "geometric");
+    prepareCalibration("touch.toolSize.calibration", "geometric");
+    addMapperAndConfigure(mapper);
+
+    // These calculations are based on the input device calibration documentation.
+    int32_t rawX = 100;
+    int32_t rawY = 200;
+    int32_t rawTouchMajor = 140;
+    int32_t rawTouchMinor = 120;
+    int32_t rawToolMajor = 180;
+    int32_t rawToolMinor = 160;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float pressure = float(rawTouchMajor) / RAW_TOUCH_MAX;
+    float size = avg(rawToolMajor, rawToolMinor) / RAW_TOOL_MAX;
+    float scale = avg(float(DISPLAY_WIDTH) / (RAW_X_MAX - RAW_X_MIN),
+            float(DISPLAY_HEIGHT) / (RAW_Y_MAX - RAW_Y_MIN));
+    float toolMajor = float(rawToolMajor) * scale;
+    float toolMinor = float(rawToolMinor) * scale;
+    float touchMajor = min(float(rawTouchMajor) * scale, toolMajor);
+    float touchMinor = min(float(rawTouchMinor) * scale, toolMinor);
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processTouchMinor(mapper, rawTouchMinor);
+    processToolMajor(mapper, rawToolMajor);
+    processToolMinor(mapper, rawToolMinor);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, touchMajor, touchMinor, toolMajor, toolMinor, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_SummedLinearCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL);
+    prepareCalibration("touch.touchSize.calibration", "pressure");
+    prepareCalibration("touch.toolSize.calibration", "linear");
+    prepareCalibration("touch.toolSize.linearScale", "10");
+    prepareCalibration("touch.toolSize.linearBias", "160");
+    prepareCalibration("touch.toolSize.isSummed", "1");
+    prepareCalibration("touch.pressure.calibration", "amplitude");
+    prepareCalibration("touch.pressure.source", "touch");
+    prepareCalibration("touch.pressure.scale", "0.01");
+    addMapperAndConfigure(mapper);
+
+    // These calculations are based on the input device calibration documentation.
+    // Note: We only provide a single common touch/tool value because the device is assumed
+    //       not to emit separate values for each pointer (isSummed = 1).
+    int32_t rawX = 100;
+    int32_t rawY = 200;
+    int32_t rawX2 = 150;
+    int32_t rawY2 = 250;
+    int32_t rawTouchMajor = 60;
+    int32_t rawToolMajor = 5;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float x2 = toDisplayX(rawX2);
+    float y2 = toDisplayY(rawY2);
+    float pressure = float(rawTouchMajor) * 0.01f;
+    float size = float(rawToolMajor) / RAW_TOOL_MAX;
+    float tool = (float(rawToolMajor) * 10.0f + 160.0f) / 2;
+    float touch = min(tool * pressure, tool);
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processToolMajor(mapper, rawToolMajor);
+    processMTSync(mapper);
+    processPosition(mapper, rawX2, rawY2);
+    processTouchMajor(mapper, rawTouchMajor);
+    processToolMajor(mapper, rawToolMajor);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_DOWN, args.action);
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_EQ(AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT),
+            args.action);
+    ASSERT_EQ(size_t(2), args.pointerCount);
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, touch, touch, tool, tool, 0));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[1],
+            x2, y2, pressure, size, touch, touch, tool, tool, 0));
+}
+
+TEST_F(MultiTouchInputMapperTest, Process_TouchToolPressureSizeAxes_AreaCalibration) {
+    MultiTouchInputMapper* mapper = new MultiTouchInputMapper(mDevice, DISPLAY_ID);
+    prepareDisplay(InputReaderPolicyInterface::ROTATION_0);
+    prepareAxes(POSITION | TOUCH | TOOL);
+    prepareCalibration("touch.touchSize.calibration", "pressure");
+    prepareCalibration("touch.toolSize.calibration", "area");
+    prepareCalibration("touch.toolSize.areaScale", "22");
+    prepareCalibration("touch.toolSize.areaBias", "1");
+    prepareCalibration("touch.toolSize.linearScale", "9.2");
+    prepareCalibration("touch.toolSize.linearBias", "3");
+    prepareCalibration("touch.pressure.calibration", "amplitude");
+    prepareCalibration("touch.pressure.source", "touch");
+    prepareCalibration("touch.pressure.scale", "0.01");
+    addMapperAndConfigure(mapper);
+
+    // These calculations are based on the input device calibration documentation.
+    int32_t rawX = 100;
+    int32_t rawY = 200;
+    int32_t rawTouchMajor = 60;
+    int32_t rawToolMajor = 5;
+
+    float x = toDisplayX(rawX);
+    float y = toDisplayY(rawY);
+    float pressure = float(rawTouchMajor) * 0.01f;
+    float size = float(rawToolMajor) / RAW_TOOL_MAX;
+    float tool = sqrtf(float(rawToolMajor) * 22.0f + 1.0f) * 9.2f + 3.0f;
+    float touch = min(tool * pressure, tool);
+
+    processPosition(mapper, rawX, rawY);
+    processTouchMajor(mapper, rawTouchMajor);
+    processToolMajor(mapper, rawToolMajor);
+    processMTSync(mapper);
+    processSync(mapper);
+
+    FakeInputDispatcher::NotifyMotionArgs args;
+    ASSERT_NO_FATAL_FAILURE(mFakeDispatcher->assertNotifyMotionWasCalled(&args));
+    ASSERT_NO_FATAL_FAILURE(assertPointerCoords(args.pointerCoords[0],
+            x, y, pressure, size, touch, touch, tool, tool, 0));
+}
+
+} // 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..eb75ed8 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 \
+	Looper.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/Looper.cpp b/libs/utils/Looper.cpp
new file mode 100644
index 0000000..a5363d6
--- /dev/null
+++ b/libs/utils/Looper.cpp
@@ -0,0 +1,596 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// A looper implementation based on epoll().
+//
+#define LOG_TAG "Looper"
+
+//#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/Looper.h>
+#include <utils/Timers.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+
+namespace android {
+
+#ifdef LOOPER_USES_EPOLL
+// Hint for number of file descriptors to be associated with the epoll instance.
+static const int EPOLL_SIZE_HINT = 8;
+
+// Maximum number of file descriptors for which to retrieve poll events each iteration.
+static const int EPOLL_MAX_EVENTS = 16;
+#endif
+
+static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
+static pthread_key_t gTLSKey = 0;
+
+Looper::Looper(bool allowNonCallbacks) :
+        mAllowNonCallbacks(allowNonCallbacks),
+        mResponseIndex(0) {
+    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);
+
+#ifdef LOOPER_USES_EPOLL
+    // Allocate the epoll instance and register the wake pipe.
+    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
+
+    struct epoll_event eventItem;
+    memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
+    eventItem.events = EPOLLIN;
+    eventItem.data.fd = mWakeReadPipeFd;
+    result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance.  errno=%d",
+            errno);
+#else
+    // 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.push(requestedFd);
+
+    Request request;
+    request.fd = mWakeReadPipeFd;
+    request.callback = NULL;
+    request.ident = 0;
+    request.data = NULL;
+    mRequests.push(request);
+
+    mPolling = false;
+    mWaiters = 0;
+#endif
+
+#ifdef LOOPER_STATISTICS
+    mPendingWakeTime = -1;
+    mPendingWakeCount = 0;
+    mSampledWakeCycles = 0;
+    mSampledWakeCountSum = 0;
+    mSampledWakeLatencySum = 0;
+
+    mSampledPolls = 0;
+    mSampledZeroPollCount = 0;
+    mSampledZeroPollLatencySum = 0;
+    mSampledTimeoutPollCount = 0;
+    mSampledTimeoutPollLatencySum = 0;
+#endif
+}
+
+Looper::~Looper() {
+    close(mWakeReadPipeFd);
+    close(mWakeWritePipeFd);
+#ifdef LOOPER_USES_EPOLL
+    close(mEpollFd);
+#endif
+}
+
+void Looper::initTLSKey() {
+    int result = pthread_key_create(& gTLSKey, threadDestructor);
+    LOG_ALWAYS_FATAL_IF(result != 0, "Could not allocate TLS key.");
+}
+
+void Looper::threadDestructor(void *st) {
+    Looper* const self = static_cast<Looper*>(st);
+    if (self != NULL) {
+        self->decStrong((void*)threadDestructor);
+    }
+}
+
+void Looper::setForThread(const sp<Looper>& looper) {
+    sp<Looper> old = getForThread(); // also has side-effect of initializing TLS
+
+    if (looper != NULL) {
+        looper->incStrong((void*)threadDestructor);
+    }
+
+    pthread_setspecific(gTLSKey, looper.get());
+
+    if (old != NULL) {
+        old->decStrong((void*)threadDestructor);
+    }
+}
+
+sp<Looper> Looper::getForThread() {
+    int result = pthread_once(& gTLSOnce, initTLSKey);
+    LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
+
+    return (Looper*)pthread_getspecific(gTLSKey);
+}
+
+sp<Looper> Looper::prepare(int opts) {
+    bool allowNonCallbacks = opts & ALOOPER_PREPARE_ALLOW_NON_CALLBACKS;
+    sp<Looper> looper = Looper::getForThread();
+    if (looper == NULL) {
+        looper = new Looper(allowNonCallbacks);
+        Looper::setForThread(looper);
+    }
+    if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
+        LOGW("Looper already prepared for this thread with a different value for the "
+                "ALOOPER_PREPARE_ALLOW_NON_CALLBACKS option.");
+    }
+    return looper;
+}
+
+bool Looper::getAllowNonCallbacks() const {
+    return mAllowNonCallbacks;
+}
+
+int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
+    int result = 0;
+    for (;;) {
+        while (mResponseIndex < mResponses.size()) {
+            const Response& response = mResponses.itemAt(mResponseIndex++);
+            if (! response.request.callback) {
+#if DEBUG_POLL_AND_WAKE
+                LOGD("%p ~ pollOnce - returning signalled identifier %d: "
+                        "fd=%d, events=0x%x, data=%p", this,
+                        response.request.ident, response.request.fd,
+                        response.events, response.request.data);
+#endif
+                if (outFd != NULL) *outFd = response.request.fd;
+                if (outEvents != NULL) *outEvents = response.events;
+                if (outData != NULL) *outData = response.request.data;
+                return response.request.ident;
+            }
+        }
+
+        if (result != 0) {
+#if DEBUG_POLL_AND_WAKE
+            LOGD("%p ~ pollOnce - returning result %d", this, result);
+#endif
+            if (outFd != NULL) *outFd = 0;
+            if (outEvents != NULL) *outEvents = NULL;
+            if (outData != NULL) *outData = NULL;
+            return result;
+        }
+
+        result = pollInner(timeoutMillis);
+    }
+}
+
+int Looper::pollInner(int timeoutMillis) {
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - waiting: timeoutMillis=%d", this, timeoutMillis);
+#endif
+
+    int result = ALOOPER_POLL_WAKE;
+    mResponses.clear();
+    mResponseIndex = 0;
+
+#ifdef LOOPER_STATISTICS
+    nsecs_t pollStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+#endif
+
+#ifdef LOOPER_USES_EPOLL
+    struct epoll_event eventItems[EPOLL_MAX_EVENTS];
+    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
+    bool acquiredLock = false;
+#else
+    // Wait for wakeAndLock() waiters to run then set mPolling to true.
+    mLock.lock();
+    while (mWaiters != 0) {
+        mResume.wait(mLock);
+    }
+    mPolling = true;
+    mLock.unlock();
+
+    size_t requestedCount = mRequestedFds.size();
+    int eventCount = poll(mRequestedFds.editArray(), requestedCount, timeoutMillis);
+#endif
+
+    if (eventCount < 0) {
+        if (errno == EINTR) {
+            goto Done;
+        }
+
+        LOGW("Poll failed with an unexpected error, errno=%d", errno);
+        result = ALOOPER_POLL_ERROR;
+        goto Done;
+    }
+
+    if (eventCount == 0) {
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - timeout", this);
+#endif
+        result = ALOOPER_POLL_TIMEOUT;
+        goto Done;
+    }
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
+#endif
+
+#ifdef LOOPER_USES_EPOLL
+    for (int i = 0; i < eventCount; i++) {
+        int fd = eventItems[i].data.fd;
+        uint32_t epollEvents = eventItems[i].events;
+        if (fd == mWakeReadPipeFd) {
+            if (epollEvents & EPOLLIN) {
+                awoken();
+            } else {
+                LOGW("Ignoring unexpected epoll events 0x%x on wake read pipe.", epollEvents);
+            }
+        } else {
+            if (! acquiredLock) {
+                mLock.lock();
+                acquiredLock = true;
+            }
+
+            ssize_t requestIndex = mRequests.indexOfKey(fd);
+            if (requestIndex >= 0) {
+                int events = 0;
+                if (epollEvents & EPOLLIN) events |= ALOOPER_EVENT_INPUT;
+                if (epollEvents & EPOLLOUT) events |= ALOOPER_EVENT_OUTPUT;
+                if (epollEvents & EPOLLERR) events |= ALOOPER_EVENT_ERROR;
+                if (epollEvents & EPOLLHUP) events |= ALOOPER_EVENT_HANGUP;
+                pushResponse(events, mRequests.valueAt(requestIndex));
+            } else {
+                LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
+                        "no longer registered.", epollEvents, fd);
+            }
+        }
+    }
+    if (acquiredLock) {
+        mLock.unlock();
+    }
+Done: ;
+#else
+    for (size_t i = 0; i < requestedCount; i++) {
+        const struct pollfd& requestedFd = mRequestedFds.itemAt(i);
+
+        short pollEvents = requestedFd.revents;
+        if (pollEvents) {
+            if (requestedFd.fd == mWakeReadPipeFd) {
+                if (pollEvents & POLLIN) {
+                    awoken();
+                } else {
+                    LOGW("Ignoring unexpected poll events 0x%x on wake read pipe.", pollEvents);
+                }
+            } else {
+                int events = 0;
+                if (pollEvents & POLLIN) events |= ALOOPER_EVENT_INPUT;
+                if (pollEvents & POLLOUT) events |= ALOOPER_EVENT_OUTPUT;
+                if (pollEvents & POLLERR) events |= ALOOPER_EVENT_ERROR;
+                if (pollEvents & POLLHUP) events |= ALOOPER_EVENT_HANGUP;
+                if (pollEvents & POLLNVAL) events |= ALOOPER_EVENT_INVALID;
+                pushResponse(events, mRequests.itemAt(i));
+            }
+            if (--eventCount == 0) {
+                break;
+            }
+        }
+    }
+
+Done:
+    // Set mPolling to false and wake up the wakeAndLock() waiters.
+    mLock.lock();
+    mPolling = false;
+    if (mWaiters != 0) {
+        mAwake.broadcast();
+    }
+    mLock.unlock();
+#endif
+
+#ifdef LOOPER_STATISTICS
+    nsecs_t pollEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
+    mSampledPolls += 1;
+    if (timeoutMillis == 0) {
+        mSampledZeroPollCount += 1;
+        mSampledZeroPollLatencySum += pollEndTime - pollStartTime;
+    } else if (timeoutMillis > 0 && result == ALOOPER_POLL_TIMEOUT) {
+        mSampledTimeoutPollCount += 1;
+        mSampledTimeoutPollLatencySum += pollEndTime - pollStartTime
+                - milliseconds_to_nanoseconds(timeoutMillis);
+    }
+    if (mSampledPolls == SAMPLED_POLLS_TO_AGGREGATE) {
+        LOGD("%p ~ poll latency statistics: %0.3fms zero timeout, %0.3fms non-zero timeout", this,
+                0.000001f * float(mSampledZeroPollLatencySum) / mSampledZeroPollCount,
+                0.000001f * float(mSampledTimeoutPollLatencySum) / mSampledTimeoutPollCount);
+        mSampledPolls = 0;
+        mSampledZeroPollCount = 0;
+        mSampledZeroPollLatencySum = 0;
+        mSampledTimeoutPollCount = 0;
+        mSampledTimeoutPollLatencySum = 0;
+    }
+#endif
+
+    for (size_t i = 0; i < mResponses.size(); i++) {
+        const Response& response = mResponses.itemAt(i);
+        if (response.request.callback) {
+#if DEBUG_POLL_AND_WAKE || DEBUG_CALLBACKS
+            LOGD("%p ~ pollOnce - invoking callback: fd=%d, events=0x%x, data=%p", this,
+                    response.request.fd, response.events, response.request.data);
+#endif
+            int callbackResult = response.request.callback(
+                    response.request.fd, response.events, response.request.data);
+            if (callbackResult == 0) {
+                removeFd(response.request.fd);
+            }
+
+            result = ALOOPER_POLL_CALLBACK;
+        }
+    }
+    return result;
+}
+
+int Looper::pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
+    if (timeoutMillis <= 0) {
+        int result;
+        do {
+            result = pollOnce(timeoutMillis, outFd, outEvents, outData);
+        } while (result == ALOOPER_POLL_CALLBACK);
+        return result;
+    } else {
+        nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC)
+                + milliseconds_to_nanoseconds(timeoutMillis);
+
+        for (;;) {
+            int result = pollOnce(timeoutMillis, outFd, outEvents, outData);
+            if (result != ALOOPER_POLL_CALLBACK) {
+                return result;
+            }
+
+            nsecs_t timeoutNanos = endTime - systemTime(SYSTEM_TIME_MONOTONIC);
+            if (timeoutNanos <= 0) {
+                return ALOOPER_POLL_TIMEOUT;
+            }
+
+            timeoutMillis = int(nanoseconds_to_milliseconds(timeoutNanos + 999999LL));
+        }
+    }
+}
+
+void Looper::wake() {
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ wake", this);
+#endif
+
+#ifdef LOOPER_STATISTICS
+    // FIXME: Possible race with awoken() but this code is for testing only and is rarely enabled.
+    if (mPendingWakeCount++ == 0) {
+        mPendingWakeTime = systemTime(SYSTEM_TIME_MONOTONIC);
+    }
+#endif
+
+    ssize_t nWrite;
+    do {
+        nWrite = write(mWakeWritePipeFd, "W", 1);
+    } while (nWrite == -1 && errno == EINTR);
+
+    if (nWrite != 1) {
+        if (errno != EAGAIN) {
+            LOGW("Could not write wake signal, errno=%d", errno);
+        }
+    }
+}
+
+void Looper::awoken() {
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ awoken", this);
+#endif
+
+#ifdef LOOPER_STATISTICS
+    if (mPendingWakeCount == 0) {
+        LOGD("%p ~ awoken: spurious!", this);
+    } else {
+        mSampledWakeCycles += 1;
+        mSampledWakeCountSum += mPendingWakeCount;
+        mSampledWakeLatencySum += systemTime(SYSTEM_TIME_MONOTONIC) - mPendingWakeTime;
+        mPendingWakeCount = 0;
+        mPendingWakeTime = -1;
+        if (mSampledWakeCycles == SAMPLED_WAKE_CYCLES_TO_AGGREGATE) {
+            LOGD("%p ~ wake statistics: %0.3fms wake latency, %0.3f wakes per cycle", this,
+                    0.000001f * float(mSampledWakeLatencySum) / mSampledWakeCycles,
+                    float(mSampledWakeCountSum) / mSampledWakeCycles);
+            mSampledWakeCycles = 0;
+            mSampledWakeCountSum = 0;
+            mSampledWakeLatencySum = 0;
+        }
+    }
+#endif
+
+    char buffer[16];
+    ssize_t nRead;
+    do {
+        nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
+    } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
+}
+
+void Looper::pushResponse(int events, const Request& request) {
+    Response response;
+    response.events = events;
+    response.request = request;
+    mResponses.push(response);
+}
+
+int Looper::addFd(int fd, int ident, int events, ALooper_callbackFunc callback, void* data) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ addFd - fd=%d, ident=%d, events=0x%x, callback=%p, data=%p", this, fd, ident,
+            events, callback, data);
+#endif
+
+    if (! callback) {
+        if (! mAllowNonCallbacks) {
+            LOGE("Invalid attempt to set NULL callback but not allowed for this looper.");
+            return -1;
+        }
+
+        if (ident < 0) {
+            LOGE("Invalid attempt to set NULL callback with ident <= 0.");
+            return -1;
+        }
+    }
+
+#ifdef LOOPER_USES_EPOLL
+    int epollEvents = 0;
+    if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN;
+    if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        Request request;
+        request.fd = fd;
+        request.ident = ident;
+        request.callback = callback;
+        request.data = data;
+
+        struct epoll_event eventItem;
+        memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
+        eventItem.events = epollEvents;
+        eventItem.data.fd = fd;
+
+        ssize_t requestIndex = mRequests.indexOfKey(fd);
+        if (requestIndex < 0) {
+            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
+            if (epollResult < 0) {
+                LOGE("Error adding epoll events for fd %d, errno=%d", fd, errno);
+                return -1;
+            }
+            mRequests.add(fd, request);
+        } else {
+            int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
+            if (epollResult < 0) {
+                LOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno);
+                return -1;
+            }
+            mRequests.replaceValueAt(requestIndex, request);
+        }
+    } // release lock
+#else
+    int pollEvents = 0;
+    if (events & ALOOPER_EVENT_INPUT) pollEvents |= POLLIN;
+    if (events & ALOOPER_EVENT_OUTPUT) pollEvents |= POLLOUT;
+
+    wakeAndLock(); // acquire lock
+
+    struct pollfd requestedFd;
+    requestedFd.fd = fd;
+    requestedFd.events = pollEvents;
+
+    Request request;
+    request.fd = fd;
+    request.ident = ident;
+    request.callback = callback;
+    request.data = data;
+    ssize_t index = getRequestIndexLocked(fd);
+    if (index < 0) {
+        mRequestedFds.push(requestedFd);
+        mRequests.push(request);
+    } else {
+        mRequestedFds.replaceAt(requestedFd, size_t(index));
+        mRequests.replaceAt(request, size_t(index));
+    }
+
+    mLock.unlock(); // release lock
+#endif
+    return 1;
+}
+
+int Looper::removeFd(int fd) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ removeFd - fd=%d", this, fd);
+#endif
+
+#ifdef LOOPER_USES_EPOLL
+    { // acquire lock
+        AutoMutex _l(mLock);
+        ssize_t requestIndex = mRequests.indexOfKey(fd);
+        if (requestIndex < 0) {
+            return 0;
+        }
+
+        int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
+        if (epollResult < 0) {
+            LOGE("Error removing epoll events for fd %d, errno=%d", fd, errno);
+            return -1;
+        }
+
+        mRequests.removeItemsAt(requestIndex);
+    } // release lock
+    return 1;
+#else
+    wakeAndLock(); // acquire lock
+
+    ssize_t index = getRequestIndexLocked(fd);
+    if (index >= 0) {
+        mRequestedFds.removeAt(size_t(index));
+        mRequests.removeAt(size_t(index));
+    }
+
+    mLock.unlock(); // release lock
+    return index >= 0;
+#endif
+}
+
+#ifndef LOOPER_USES_EPOLL
+ssize_t Looper::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 Looper::wakeAndLock() {
+    mLock.lock();
+
+    mWaiters += 1;
+    while (mPolling) {
+        wake();
+        mAwake.wait(mLock);
+    }
+
+    mWaiters -= 1;
+    if (mWaiters == 0) {
+        mResume.signal();
+    }
+}
+#endif
+
+} // namespace android
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
new file mode 100644
index 0000000..2c3724c
--- /dev/null
+++ b/libs/utils/ObbFile.cpp
@@ -0,0 +1,354 @@
+/*
+ * 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 33 /* 32-bit signature version (4 bytes)
+                           * 32-bit package version (4 bytes)
+                           * 32-bit flags (4 bytes)
+                           * 64-bit salt (8 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 kSaltOffset           12
+#define kPackageNameLenOffset 20
+#define kPackageNameOffset    24
+
+/*
+ * 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)
+{
+    memset(mSalt, 0, sizeof(mSalt));
+}
+
+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\n", 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);
+
+    memcpy(&mSalt, (unsigned char*)scanBuf + kSaltOffset, sizeof(mSalt));
+
+    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\n");
+        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\n", 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\n");
+        return false;
+    }
+
+    put4LE(intBuf, mFlags);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package version\n");
+        return false;
+    }
+
+    if (write(fd, mSalt, sizeof(mSalt)) != (ssize_t)sizeof(mSalt)) {
+        LOGW("couldn't write salt: %s\n", strerror(errno));
+        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\n", strerror(errno));
+        return false;
+    }
+
+    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
+        LOGW("couldn't write package name: %s\n", 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\n", 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\n", 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/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..1f62ac5
--- /dev/null
+++ b/libs/utils/StreamingZipInflater.cpp
@@ -0,0 +1,226 @@
+/*
+ * 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_NDEBUG 1
+#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) {
+                LOGD("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..4261196 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -22,6 +22,7 @@
 #include <utils/ZipFileRO.h>
 #include <utils/Log.h>
 #include <utils/misc.h>
+#include <utils/threads.h>
 
 #include <zlib.h>
 
@@ -29,6 +30,38 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <assert.h>
+#include <unistd.h>
+
+#if HAVE_PRINTF_ZD
+#  define ZD "%zd"
+#  define ZD_TYPE ssize_t
+#else
+#  define ZD "%ld"
+#  define ZD_TYPE long
+#endif
+
+/*
+ * We must open binary files using open(path, ... | O_BINARY) under Windows.
+ * Otherwise strange read errors will happen.
+ */
+#ifndef O_BINARY
+#  define O_BINARY  0
+#endif
+
+/*
+ * 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 +71,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
@@ -68,6 +102,16 @@
  */
 #define kZipEntryAdj        10000
 
+ZipFileRO::~ZipFileRO() {
+    free(mHashTable);
+    if (mDirectoryMap)
+        mDirectoryMap->release();
+    if (mFd >= 0)
+        TEMP_FAILURE_RETRY(close(mFd));
+    if (mFileName)
+        free(mFileName);
+}
+
 /*
  * Convert a ZipEntryRO to a hash table index, verifying that it's in a
  * valid range.
@@ -90,185 +134,251 @@
 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.
      */
-    fd = ::open(zipFileName, O_RDONLY);
+    fd = ::open(zipFileName, O_RDONLY | O_BINARY);
     if (fd < 0) {
         LOGW("Unable to open zip '%s': %s\n", zipFileName, strerror(errno));
         return NAME_NOT_FOUND;
     }
 
-    length = lseek(fd, 0, SEEK_END);
-    if (length < 0) {
-        close(fd);
+    mFileLength = lseek(fd, 0, SEEK_END);
+    if (mFileLength < kEOCDLen) {
+        TEMP_FAILURE_RETRY(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;
+    TEMP_FAILURE_RETRY(close(fd));
+    return UNKNOWN_ERROR;
 }
 
 /*
  * Parse the Zip archive, verifying its contents and initializing internal
  * data structures.
  */
+bool ZipFileRO::mapCentralDirectory(void)
+{
+    ssize_t readAmount = kMaxEOCDSearch;
+    if (readAmount > (ssize_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", header);
+            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 ", expected " ZD ". Failed: %s\n",
+            (ZD_TYPE) actual, (ZD_TYPE) 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,
+                (ZD_TYPE) dirOffset, (ZD_TYPE) (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), (ZD_TYPE) 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.
  */
@@ -302,10 +412,18 @@
 /*
  * Find a matching entry.
  *
- * Returns 0 if not found.
+ * Returns NULL if not found.
  */
 ZipEntryRO ZipFileRO::findEntryByName(const char* fileName) const
 {
+    /*
+     * If the ZipFileRO instance is not initialized, the entry number will
+     * end up being garbage since mHashTableSize is -1.
+     */
+    if (mHashTableSize <= 0) {
+        return NULL;
+    }
+
     int nameLen = strlen(fileName);
     unsigned int hash = computeHash(fileName, nameLen);
     int ent = hash & (mHashTableSize-1);
@@ -315,7 +433,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 +472,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 +502,117 @@
     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];
+
+#ifdef HAVE_PREAD
+        /*
+         * This file descriptor might be from zygote's preloaded assets,
+         * so we need to do an pread() instead of a lseek() + read() to
+         * guarantee atomicity across the processes with the shared file
+         * descriptors.
+         */
+        ssize_t actual =
+                TEMP_FAILURE_RETRY(pread(mFd, lfhBuf, sizeof(lfhBuf), localHdrOffset));
+
+        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; wanted: offset=%ld data=0x%08x; "
+                    "got: data=0x%08lx\n",
+                    localHdrOffset, kLFHSignature, get4LE(lfhBuf));
+            return false;
+        }
+#else /* HAVE_PREAD */
+        /*
+         * For hosts don't have pread() we cannot guarantee atomic reads from
+         * an offset in a file. Android should never run on those platforms.
+         * File descriptors inherited from a fork() share file offsets and
+         * there would be nothing to protect from two different processes
+         * calling lseek() concurrently.
+         */
+
+        {
+            AutoMutex _l(mFdLock);
+
+            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) {
+                off_t actualOffset = lseek(mFd, 0, SEEK_CUR);
+                LOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; "
+                        "got: offset=" ZD " data=0x%08lx\n",
+                        localHdrOffset, kLFHSignature, (ZD_TYPE) actualOffset, get4LE(lfhBuf));
+                return false;
+            }
+        }
+#endif /* HAVE_PREAD */
+
+        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, (ZD_TYPE) 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, (ZD_TYPE) uncompLen, (long) cdOffset);
+            return false;
+        }
+
         *pOffset = dataOffset;
     }
+
     return true;
 }
 
@@ -457,14 +648,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 +671,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,20 +705,22 @@
      * 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))
-            goto bail;
+        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
+            goto unmap;
     }
 
     if (compLen > kSequentialMin)
-        mFileMap->advise(FileMap::NORMAL);
+        file->advise(FileMap::NORMAL);
 
     result = true;
 
+unmap:
+    file->release();
 bail:
     return result;
 }
@@ -537,34 +737,41 @@
     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;
+    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);
-            goto bail;
+            goto unmap;
+        } else if ((size_t) actual != uncompLen) {
+            LOGE("Partial write during uncompress (" ZD " of " ZD ")\n",
+                (ZD_TYPE) actual, (ZD_TYPE) uncompLen);
+            goto unmap;
         } else {
             LOGI("+++ successful write\n");
         }
     } else {
-        if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
-            goto bail;
+        if (!inflateBuffer(fd, ptr, uncompLen, compLen))
+            goto unmap;
     }
 
     result = true;
 
+unmap:
+    file->release();
 bail:
     return result;
 }
@@ -573,7 +780,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 +789,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 +799,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,9 +826,9 @@
     }
 
     /* paranoia */
-    if ((long) zstream.total_out != uncompLen) {
-        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
-            zstream.total_out, uncompLen);
+    if (zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
+            zstream.total_out, (ZD_TYPE) uncompLen);
         goto z_bail;
     }
 
@@ -638,10 +845,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 +856,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 +866,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,9 +915,9 @@
     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",
-            zstream.total_out, uncompLen);
+    if (zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs " ZD ")\n",
+            zstream.total_out, (ZD_TYPE) uncompLen);
         goto z_bail;
     }
 
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
new file mode 100644
index 0000000..00077ee
--- /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 \
+	Looper_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/Looper_test.cpp b/libs/utils/tests/Looper_test.cpp
new file mode 100644
index 0000000..cea1313
--- /dev/null
+++ b/libs/utils/tests/Looper_test.cpp
@@ -0,0 +1,425 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <utils/Looper.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<Looper> mLooper;
+
+public:
+    DelayedWake(int delayMillis, const sp<Looper> looper) :
+        DelayedTask(delayMillis), mLooper(looper) {
+    }
+
+protected:
+    virtual void doTask() {
+        mLooper->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<Looper>& looper, int fd, int events) {
+        looper->addFd(fd, 0, events, staticHandler, this);
+    }
+
+protected:
+    virtual ~CallbackHandler() { }
+
+    virtual int handler(int fd, int events) = 0;
+
+private:
+    static int staticHandler(int fd, int events, void* data) {
+        return static_cast<CallbackHandler*>(data)->handler(fd, events);
+    }
+};
+
+class StubCallbackHandler : public CallbackHandler {
+public:
+    int nextResult;
+    int callbackCount;
+
+    int fd;
+    int events;
+
+    StubCallbackHandler(int nextResult) : nextResult(nextResult),
+            callbackCount(0), fd(-1), events(-1) {
+    }
+
+protected:
+    virtual int handler(int fd, int events) {
+        callbackCount += 1;
+        this->fd = fd;
+        this->events = events;
+        return nextResult;
+    }
+};
+
+class LooperTest : public testing::Test {
+protected:
+    sp<Looper> mLooper;
+
+    virtual void SetUp() {
+        mLooper = new Looper(true);
+    }
+
+    virtual void TearDown() {
+        mLooper.clear();
+    }
+};
+
+
+TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNotAwoken_WaitsForTimeout) {
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout";
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
+}
+
+TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenBeforeWaiting_ImmediatelyReturns) {
+    mLooper->wake();
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->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(ALOOPER_POLL_WAKE, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken";
+}
+
+TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndAwokenWhileWaiting_PromptlyReturns) {
+    sp<DelayedWake> delayedWake = new DelayedWake(100, mLooper);
+    delayedWake->run();
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(1000);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal wake delay";
+    EXPECT_EQ(ALOOPER_POLL_WAKE, result)
+            << "pollOnce result should be ALOOPER_POLL_CALLBACK because loop was awoken";
+}
+
+TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoRegisteredFDs_ImmediatelyReturns) {
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
+}
+
+TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndNoSignalledFDs_ImmediatelyReturns) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not have been invoked because FD was not signalled";
+}
+
+TEST_F(LooperTest, PollOnce_WhenZeroTimeoutAndSignalledFD_ImmediatelyInvokesCallbackAndReturns) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    ASSERT_EQ(OK, pipe.writeSignal());
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(0);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(0, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should be approx. zero";
+    EXPECT_EQ(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_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(ALOOPER_EVENT_INPUT, handler.events)
+            << "callback should have received ALOOPER_EVENT_INPUT as events";
+}
+
+TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndNoSignalledFDs_WaitsForTimeoutAndReturns) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->pollOnce(100);
+    int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime());
+
+    EXPECT_NEAR(100, elapsedMillis, TIMING_TOLERANCE_MS)
+            << "elapsed time should approx. equal timeout";
+    EXPECT_EQ(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not have been invoked because FD was not signalled";
+}
+
+TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDBeforeWaiting_ImmediatelyInvokesCallbackAndReturns) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    pipe.writeSignal();
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->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(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_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(ALOOPER_EVENT_INPUT, handler.events)
+            << "callback should have received ALOOPER_EVENT_INPUT as events";
+}
+
+TEST_F(LooperTest, PollOnce_WhenNonZeroTimeoutAndSignalledFDWhileWaiting_PromptlyInvokesCallbackAndReturns) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+    sp<DelayedWriteSignal> delayedWriteSignal = new DelayedWriteSignal(100, & pipe);
+
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+    delayedWriteSignal->run();
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->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(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_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(ALOOPER_EVENT_INPUT, handler.events)
+            << "callback should have received ALOOPER_EVENT_INPUT as events";
+}
+
+TEST_F(LooperTest, PollOnce_WhenCallbackAddedThenRemoved_CallbackShouldNotBeInvoked) {
+    Pipe pipe;
+    StubCallbackHandler handler(true);
+
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+    pipe.writeSignal(); // would cause FD to be considered signalled
+    mLooper->removeFd(pipe.receiveFd);
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->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(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
+    EXPECT_EQ(0, handler.callbackCount)
+            << "callback should not be invoked";
+}
+
+TEST_F(LooperTest, PollOnce_WhenCallbackReturnsFalse_CallbackShouldNotBeInvokedAgainLater) {
+    Pipe pipe;
+    StubCallbackHandler handler(false);
+
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+
+    // First loop: Callback is registered and FD is signalled.
+    pipe.writeSignal();
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->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(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_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 = mLooper->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(ALOOPER_POLL_TIMEOUT, result)
+            << "pollOnce result should be ALOOPER_POLL_TIMEOUT";
+    EXPECT_EQ(1, handler.callbackCount)
+            << "callback should not be invoked this time";
+}
+
+TEST_F(LooperTest, PollOnce_WhenNonCallbackFdIsSignalled_ReturnsIdent) {
+    const int expectedIdent = 5;
+    void* expectedData = this;
+
+    Pipe pipe;
+
+    pipe.writeSignal();
+    mLooper->addFd(pipe.receiveFd, expectedIdent, ALOOPER_EVENT_INPUT, NULL, expectedData);
+
+    StopWatch stopWatch("pollOnce");
+    int fd;
+    int events;
+    void* data;
+    int result = mLooper->pollOnce(100, &fd, &events, &data);
+    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(expectedIdent, result)
+            << "pollOnce result should be the ident of the FD that was signalled";
+    EXPECT_EQ(pipe.receiveFd, fd)
+            << "pollOnce should have returned the received pipe fd";
+    EXPECT_EQ(ALOOPER_EVENT_INPUT, events)
+            << "pollOnce should have returned ALOOPER_EVENT_INPUT as events";
+    EXPECT_EQ(expectedData, data)
+            << "pollOnce should have returned the data";
+}
+
+TEST_F(LooperTest, AddFd_WhenCallbackAdded_ReturnsOne) {
+    Pipe pipe;
+    int result = mLooper->addFd(pipe.receiveFd, 0, ALOOPER_EVENT_INPUT, NULL, NULL);
+
+    EXPECT_EQ(1, result)
+            << "addFd should return 1 because FD was added";
+}
+
+TEST_F(LooperTest, AddFd_WhenIdentIsNegativeAndCallbackIsNull_ReturnsError) {
+    Pipe pipe;
+    int result = mLooper->addFd(pipe.receiveFd, -1, ALOOPER_EVENT_INPUT, NULL, NULL);
+
+    EXPECT_EQ(-1, result)
+            << "addFd should return -1 because arguments were invalid";
+}
+
+TEST_F(LooperTest, AddFd_WhenNoCallbackAndAllowNonCallbacksIsFalse_ReturnsError) {
+    Pipe pipe;
+    sp<Looper> looper = new Looper(false /*allowNonCallbacks*/);
+    int result = looper->addFd(pipe.receiveFd, 0, 0, NULL, NULL);
+
+    EXPECT_EQ(-1, result)
+            << "addFd should return -1 because arguments were invalid";
+}
+
+TEST_F(LooperTest, RemoveFd_WhenCallbackNotAdded_ReturnsZero) {
+    int result = mLooper->removeFd(1);
+
+    EXPECT_EQ(0, result)
+            << "removeFd should return 0 because FD not registered";
+}
+
+TEST_F(LooperTest, RemoveFd_WhenCallbackAddedThenRemovedTwice_ReturnsOnceFirstTimeAndReturnsZeroSecondTime) {
+    Pipe pipe;
+    StubCallbackHandler handler(false);
+    handler.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+
+    // First time.
+    int result = mLooper->removeFd(pipe.receiveFd);
+
+    EXPECT_EQ(1, result)
+            << "removeFd should return 1 first time because FD was registered";
+
+    // Second time.
+    result = mLooper->removeFd(pipe.receiveFd);
+
+    EXPECT_EQ(0, result)
+            << "removeFd should return 0 second time because FD was no longer registered";
+}
+
+TEST_F(LooperTest, PollOnce_WhenCallbackAddedTwice_OnlySecondCallbackShouldBeInvoked) {
+    Pipe pipe;
+    StubCallbackHandler handler1(true);
+    StubCallbackHandler handler2(true);
+
+    handler1.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT);
+    handler2.setCallback(mLooper, pipe.receiveFd, ALOOPER_EVENT_INPUT); // replace it
+    pipe.writeSignal(); // would cause FD to be considered signalled
+
+    StopWatch stopWatch("pollOnce");
+    int result = mLooper->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(ALOOPER_POLL_CALLBACK, result)
+            << "pollOnce result should be ALOOPER_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/ObbFile_test.cpp b/libs/utils/tests/ObbFile_test.cpp
new file mode 100644
index 0000000..46b30c2
--- /dev/null
+++ b/libs/utils/tests/ObbFile_test.cpp
@@ -0,0 +1,100 @@
+/*
+ * 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>
+#include <string.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);
+#define SALT_SIZE 8
+    unsigned char salt[SALT_SIZE] = {0x01, 0x10, 0x55, 0xAA, 0xFF, 0x00, 0x5A, 0xA5};
+    EXPECT_TRUE(mObbFile->setSalt(salt, SALT_SIZE))
+            << "Salt should be successfully set";
+
+    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";
+
+    size_t saltLen;
+    const unsigned char* newSalt = mObbFile->getSalt(&saltLen);
+
+    EXPECT_EQ(sizeof(salt), saltLen)
+            << "salt sizes were not the same";
+
+    for (int i = 0; i < sizeof(salt); i++) {
+        EXPECT_EQ(salt[i], newSalt[i])
+                << "salt character " << i << " should be equal";
+    }
+    EXPECT_TRUE(memcmp(newSalt, salt, sizeof(salt)) == 0)
+            << "salts should be the same";
+}
+
+}
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..bfac71b 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
@@ -76,7 +78,17 @@
 typedef void *EGLNativeWindowType;
 typedef void *EGLNativePixmapType;
 
-#elif defined(__unix__) && !defined(ANDROID)
+#elif defined(__ANDROID__) || defined(ANDROID)
+
+#include <android/native_window.h>
+
+struct egl_native_pixmap_t;
+
+typedef struct ANativeWindow*           EGLNativeWindowType;
+typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
+typedef void*                           EGLNativeDisplayType;
+
+#elif defined(__unix__)
 
 /* X11 (tentative)  */
 #include <X11/Xlib.h>
@@ -86,16 +98,6 @@
 typedef Pixmap   EGLNativePixmapType;
 typedef Window   EGLNativeWindowType;
 
-
-#elif defined(ANDROID)
-
-struct android_native_window_t;
-struct egl_native_pixmap_t;
-
-typedef struct android_native_window_t* EGLNativeWindowType;
-typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
-typedef void*                           EGLNativeDisplayType;
-
 #else
 #error "Platform not recognized"
 #endif
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..65ab5e4 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,19 @@
 #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_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_TEXTURE_EXTERNAL_OES                                 0x8D65
+#define GL_SAMPLER_EXTERNAL_OES                                 0x8D66
+#define GL_TEXTURE_BINDING_EXTERNAL_OES                         0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES                     0x8D68
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension tokens
  *------------------------------------------------------------------------*/
@@ -219,15 +237,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 +650,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 +770,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_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension functions
  *------------------------------------------------------------------------*/
@@ -591,14 +805,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..9db4e25 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,14 @@
 #define GL_INT_10_10_10_2_OES                                   0x8DF7
 #endif
 
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_TEXTURE_EXTERNAL_OES                                 0x8D65
+#define GL_SAMPLER_EXTERNAL_OES                                 0x8D66
+#define GL_TEXTURE_BINDING_EXTERNAL_OES                         0x8D67
+#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES                     0x8D68
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension tokens
  *------------------------------------------------------------------------*/
@@ -141,11 +171,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 +182,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 +264,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 +283,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 +308,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 +390,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 +405,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 +435,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 +448,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 +484,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 +549,11 @@
 #define GL_OES_vertex_type_10_10_10_2 1
 #endif
 
+/* GL_OES_EGL_image_external */
+#ifndef GL_OES_EGL_image_external
+#define GL_OES_EGL_image_external 1
+#endif
+
 /*------------------------------------------------------------------------*
  * AMD extension functions
  *------------------------------------------------------------------------*/
@@ -395,20 +568,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 +586,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 +597,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 +715,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 +740,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 6cb146c..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		            \
@@ -37,6 +34,10 @@
 	LOCAL_CFLAGS += -fstrict-aliasing
 endif
 
+ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
+    LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
+endif
+
 ifneq ($(TARGET_SIMULATOR),true)
     # we need to access the private Bionic header <bionic_tls.h>
     # on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
@@ -47,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 b6e0aae..662a1fa 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)
@@ -869,6 +833,9 @@
     static bool mask(GLint reqValue, GLint confValue) {
         return (confValue & reqValue) == reqValue;
     }
+    static bool ignore(GLint reqValue, GLint confValue) {
+        return true;
+    }
 };
 
 // ----------------------------------------------------------------------------
@@ -876,14 +843,13 @@
 #define VERSION_MAJOR 1
 #define VERSION_MINOR 2
 static char const * const gVendorString     = "Google Inc.";
-static char const * const gVersionString    = "1.2 Android Driver 1.1.0";
+static char const * const gVersionString    = "1.2 Android Driver 1.2.0";
 static char const * const gClientApiString  = "OpenGL ES";
 static char const * const gExtensionsString =
         "EGL_KHR_image_base "
         // "KHR_image_pixmap "
         "EGL_ANDROID_image_native_buffer "
         "EGL_ANDROID_swap_rectangle "
-        "EGL_ANDROID_get_render_buffer "
         ;
 
 // ----------------------------------------------------------------------------
@@ -936,8 +902,6 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "eglGetRenderBufferANDROID", 
-            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
 /*
@@ -986,6 +950,7 @@
         { EGL_RED_SIZE,         5 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        0 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -997,6 +962,7 @@
         { EGL_RED_SIZE,         5 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        1 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGB_565 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1009,6 +975,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        6 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1020,6 +987,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        7 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBX_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1032,6 +1000,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        2 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1043,6 +1012,7 @@
         { EGL_RED_SIZE,         8 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        3 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_RGBA_8888 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1055,6 +1025,7 @@
         { EGL_RED_SIZE,         0 },
         { EGL_DEPTH_SIZE,       0 },
         { EGL_CONFIG_ID,        4 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1066,6 +1037,7 @@
         { EGL_RED_SIZE,         0 },
         { EGL_DEPTH_SIZE,      16 },
         { EGL_CONFIG_ID,        5 },
+        { EGL_NATIVE_VISUAL_ID, GGL_PIXEL_FORMAT_A_8 },
         { EGL_SURFACE_TYPE,     EGL_WINDOW_BIT|EGL_PBUFFER_BIT|EGL_PIXMAP_BIT },
 };
 
@@ -1091,11 +1063,11 @@
         { EGL_CONFIG_CAVEAT,              config_management_t::exact   },
         { EGL_CONFIG_ID,                  config_management_t::exact   },
         { EGL_LEVEL,                      config_management_t::exact   },
-        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::exact   },
-        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::exact   },
-        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::exact   },
+        { EGL_MAX_PBUFFER_HEIGHT,         config_management_t::ignore   },
+        { EGL_MAX_PBUFFER_PIXELS,         config_management_t::ignore   },
+        { EGL_MAX_PBUFFER_WIDTH,          config_management_t::ignore   },
         { EGL_NATIVE_RENDERABLE,          config_management_t::exact   },
-        { EGL_NATIVE_VISUAL_ID,           config_management_t::exact   },
+        { EGL_NATIVE_VISUAL_ID,           config_management_t::ignore   },
         { EGL_NATIVE_VISUAL_TYPE,         config_management_t::exact   },
         { EGL_SAMPLES,                    config_management_t::exact   },
         { EGL_SAMPLE_BUFFERS,             config_management_t::exact   },
@@ -1300,7 +1272,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 +1295,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 +1497,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 +2127,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..8b4136a 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -28,16 +28,12 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include <hardware/copybit.h>
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
 
 static char const * const gVendorString     = "Android";
-static char const * const gRendererString   = "Android PixelFlinger 1.3";
+static char const * const gRendererString   = "Android PixelFlinger 1.4";
 static char const * const gVersionString    = "OpenGL ES-CM 1.0";
 static char const * const gExtensionsString =
     "GL_OES_byte_coordinates "              // OK
@@ -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 9407bd5..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);
@@ -1515,7 +1497,7 @@
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
-    if (x<0 || x<0) {
+    if (x<0 || y<0) {
         ogles_error(c, GL_INVALID_VALUE);
         return;
     }
@@ -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/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 5d6ac26..747c829 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -136,30 +136,24 @@
      */
     
     void* dso;
-    char path[PATH_MAX];
     int index = int(display);
     driver_t* hnd = 0;
-    const char* const format = "/system/lib/egl/lib%s_%s.so";
     
     char const* tag = getTag(index, impl);
     if (tag) {
-        snprintf(path, PATH_MAX, format, "GLES", tag);
-        dso = load_driver(path, cnx, EGL | GLESv1_CM | GLESv2);
+        dso = load_driver("GLES", tag, cnx, EGL | GLESv1_CM | GLESv2);
         if (dso) {
             hnd = new driver_t(dso);
         } else {
             // Always load EGL first
-            snprintf(path, PATH_MAX, format, "EGL", tag);
-            dso = load_driver(path, cnx, EGL);
+            dso = load_driver("EGL", tag, cnx, EGL);
             if (dso) {
                 hnd = new driver_t(dso);
 
                 // TODO: make this more automated
-                snprintf(path, PATH_MAX, format, "GLESv1_CM", tag);
-                hnd->set( load_driver(path, cnx, GLESv1_CM), GLESv1_CM );
+                hnd->set( load_driver("GLESv1_CM", tag, cnx, GLESv1_CM), GLESv1_CM );
 
-                snprintf(path, PATH_MAX, format, "GLESv2", tag);
-                hnd->set( load_driver(path, cnx, GLESv2), GLESv2 );
+                hnd->set( load_driver("GLESv2", tag, cnx, GLESv2), GLESv2 );
             }
         }
     }
@@ -222,12 +216,20 @@
     }
 }
 
-void *Loader::load_driver(const char* driver_absolute_path,
+void *Loader::load_driver(const char* kind, const char *tag,
         egl_connection_t* cnx, uint32_t mask)
 {
+    char driver_absolute_path[PATH_MAX];
+    const char* const search1 = "/vendor/lib/egl/lib%s_%s.so";
+    const char* const search2 = "/system/lib/egl/lib%s_%s.so";
+
+    snprintf(driver_absolute_path, PATH_MAX, search1, kind, tag);
     if (access(driver_absolute_path, R_OK)) {
-        // this happens often, we don't want to log an error
-        return 0;
+        snprintf(driver_absolute_path, PATH_MAX, search2, kind, tag);
+        if (access(driver_absolute_path, R_OK)) {
+            // this happens often, we don't want to log an error
+            return 0;
+        }
     }
 
     void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
diff --git a/opengl/libs/EGL/Loader.h b/opengl/libs/EGL/Loader.h
index 8659b0b..580d6e4 100644
--- a/opengl/libs/EGL/Loader.h
+++ b/opengl/libs/EGL/Loader.h
@@ -74,7 +74,7 @@
     
 private:
     Loader();
-    void *load_driver(const char* driver, egl_connection_t* cnx, uint32_t mask);
+    void *load_driver(const char* kind, const char *tag, egl_connection_t* cnx, uint32_t mask);
 
     static __attribute__((noinline))
     void init_api(void* dso, 
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 89b3e1f..ab260d5 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,17 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "eglGetRenderBufferANDROID", 
-            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
+    { "glEGLImageTargetTexture2DOES",
+            (__eglMustCastToProperFunctionPointerType)NULL },
+    { "glEGLImageTargetRenderbufferStorageOES",
+            (__eglMustCastToProperFunctionPointerType)NULL },
 };
 
-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))() 
@@ -422,13 +432,14 @@
 
 // ----------------------------------------------------------------------------
 
-static void gl_no_context() {
+static int gl_no_context() {
     tls_t* tls = getTLS();
     if (tls->logCallWithNoContext == EGL_TRUE) {
         tls->logCallWithNoContext = EGL_FALSE;
         LOGE("call to OpenGL ES API with no current context "
              "(logged once per thread)");
     }
+    return 0;
 }
 
 static void early_egl_init(void) 
@@ -441,6 +452,7 @@
             (uint32_t*)(void*)&gHooksNoContext, 
             addr, 
             sizeof(gHooksNoContext));
+
     setGlThreadSpecific(&gHooksNoContext);
 }
 
@@ -477,20 +489,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 +725,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 +734,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 +810,7 @@
     
     dp->refs--;
     dp->numTotalConfigs = 0;
+    delete [] dp->configs;
     clearTLS();
     return res;
 }
@@ -804,14 +831,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 +860,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,10 +869,12 @@
     EGLint patch_index = -1;
     GLint attr;
     size_t size = 0;
-    while ((attr=attrib_list[size]) != EGL_NONE) {
-        if (attr == EGL_CONFIG_ID)
-            patch_index = size;
-        size += 2;
+    if (attrib_list) {
+        while ((attr=attrib_list[size]) != EGL_NONE) {
+            if (attr == EGL_CONFIG_ID)
+                patch_index = size;
+            size += 2;
+        }
     }
     if (patch_index >= 0) {
         size += 2; // we need copy the sentinel as well
@@ -856,16 +884,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);
 
@@ -878,12 +910,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;
             }
@@ -893,6 +926,7 @@
         return res;
     }
 
+
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
@@ -900,15 +934,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);
                         }
@@ -928,18 +961,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);
 }
 
 // ----------------------------------------------------------------------------
@@ -951,13 +982,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;
         }
     }
@@ -969,13 +1001,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;
         }
     }
@@ -986,13 +1019,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;
         }
     }
@@ -1028,23 +1062,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
@@ -1062,7 +1108,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;
         }
     }
@@ -1207,8 +1254,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)
@@ -1295,16 +1350,18 @@
 EGLint eglGetError(void)
 {
     EGLint result = EGL_SUCCESS;
+    EGLint err;
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
-        EGLint err = EGL_SUCCESS;
+        err = EGL_SUCCESS;
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso)
             err = cnx->egl.eglGetError();
         if (err!=EGL_SUCCESS && result==EGL_SUCCESS)
             result = err;
     }
+    err = getError();
     if (result == EGL_SUCCESS)
-        result = getError();
+        result = err;
     return result;
 }
 
@@ -1323,55 +1380,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)
@@ -1580,13 +1637,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);
 }
@@ -1720,7 +1777,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;
@@ -1758,19 +1815,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.cpp b/opengl/libs/GLES2/gl2.cpp
index 924737e..18dd483 100644
--- a/opengl/libs/GLES2/gl2.cpp
+++ b/opengl/libs/GLES2/gl2.cpp
@@ -58,6 +58,7 @@
             "ldr   r12, [r12, %[tls]] \n"                       \
             "cmp   r12, #0            \n"                       \
             "ldrne pc,  [r12, %[api]] \n"                       \
+            "mov   r0, #0             \n"                       \
             "bx    lr                 \n"                       \
             :                                                   \
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
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.cpp b/opengl/libs/GLES_CM/gl.cpp
index d71ff76..ee29f12 100644
--- a/opengl/libs/GLES_CM/gl.cpp
+++ b/opengl/libs/GLES_CM/gl.cpp
@@ -114,6 +114,7 @@
             "ldr   r12, [r12, %[tls]] \n"                       \
             "cmp   r12, #0            \n"                       \
             "ldrne pc,  [r12, %[api]] \n"                       \
+            "mov   r0, #0             \n"                       \
             "bx    lr                 \n"                       \
             :                                                   \
             : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
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/configdump/Android.mk b/opengl/tests/configdump/Android.mk
new file mode 100644
index 0000000..3f7c915
--- /dev/null
+++ b/opengl/tests/configdump/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	configdump.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+    libEGL \
+    libGLESv1_CM
+
+LOCAL_MODULE:= test-opengl-configdump
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/configdump/configdump.cpp b/opengl/tests/configdump/configdump.cpp
new file mode 100644
index 0000000..69b9eb6
--- /dev/null
+++ b/opengl/tests/configdump/configdump.cpp
@@ -0,0 +1,89 @@
+/*
+** Copyright 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 <EGL/egl.h>
+
+#define ATTRIBUTE(_attr) { _attr, #_attr }
+
+struct Attribute {
+    EGLint attribute;
+    char const* name;
+};
+
+Attribute attributes[] = {
+        ATTRIBUTE( EGL_BUFFER_SIZE ),
+        ATTRIBUTE( EGL_ALPHA_SIZE ),
+        ATTRIBUTE( EGL_BLUE_SIZE ),
+        ATTRIBUTE( EGL_GREEN_SIZE ),
+        ATTRIBUTE( EGL_RED_SIZE ),
+        ATTRIBUTE( EGL_DEPTH_SIZE ),
+        ATTRIBUTE( EGL_STENCIL_SIZE ),
+        ATTRIBUTE( EGL_CONFIG_CAVEAT ),
+        ATTRIBUTE( EGL_CONFIG_ID ),
+        ATTRIBUTE( EGL_LEVEL ),
+        ATTRIBUTE( EGL_MAX_PBUFFER_HEIGHT ),
+        ATTRIBUTE( EGL_MAX_PBUFFER_WIDTH ),
+        ATTRIBUTE( EGL_MAX_PBUFFER_PIXELS ),
+        ATTRIBUTE( EGL_NATIVE_RENDERABLE ),
+        ATTRIBUTE( EGL_NATIVE_VISUAL_ID ),
+        ATTRIBUTE( EGL_NATIVE_VISUAL_TYPE ),
+        ATTRIBUTE( EGL_SAMPLES ),
+        ATTRIBUTE( EGL_SAMPLE_BUFFERS ),
+        ATTRIBUTE( EGL_SURFACE_TYPE ),
+        ATTRIBUTE( EGL_TRANSPARENT_TYPE ),
+        ATTRIBUTE( EGL_TRANSPARENT_BLUE_VALUE ),
+        ATTRIBUTE( EGL_TRANSPARENT_GREEN_VALUE ),
+        ATTRIBUTE( EGL_TRANSPARENT_RED_VALUE ),
+        ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGB ),
+        ATTRIBUTE( EGL_BIND_TO_TEXTURE_RGBA ),
+        ATTRIBUTE( EGL_MIN_SWAP_INTERVAL ),
+        ATTRIBUTE( EGL_MAX_SWAP_INTERVAL ),
+        ATTRIBUTE( EGL_LUMINANCE_SIZE ),
+        ATTRIBUTE( EGL_ALPHA_MASK_SIZE ),
+        ATTRIBUTE( EGL_COLOR_BUFFER_TYPE ),
+        ATTRIBUTE( EGL_RENDERABLE_TYPE ),
+        ATTRIBUTE( EGL_MATCH_NATIVE_PIXMAP ),
+        ATTRIBUTE( EGL_CONFORMANT ),
+};
+
+
+int main(int argc, char** argv)
+{
+    EGLConfig* configs;
+    EGLint n;
+
+    EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(dpy, 0, 0);
+    eglGetConfigs(dpy, NULL, 0, &n);
+    configs = new EGLConfig[n];
+    eglGetConfigs(dpy, configs, n, &n);
+
+    for (EGLint i=0 ; i<n ; i++) {
+        printf("EGLConfig[%d]\n", i);
+        for (int attr = 0 ; attr<sizeof(attributes)/sizeof(Attribute) ; attr++) {
+            EGLint value;
+            eglGetConfigAttrib(dpy, configs[i], attributes[attr].attribute, &value);
+            printf("\t%-32s: %10d (0x%08x)\n", attributes[attr].name, value, value);
+        }
+    }
+
+    delete [] configs;
+    eglTerminate(dpy);
+    return 0;
+}
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/tests/gl_jni/jni/gl_code.cpp b/opengl/tests/gl_jni/jni/gl_code.cpp
index 33b25ab..f031c79 100644
--- a/opengl/tests/gl_jni/jni/gl_code.cpp
+++ b/opengl/tests/gl_jni/jni/gl_code.cpp
@@ -180,4 +180,5 @@
 JNIEXPORT void JNICALL Java_com_android_gljni_GLJNILib_changeBackground(JNIEnv * env, jobject obj)
 {
     background = 1.0f - background;
-}
\ No newline at end of file
+}
+
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
new file mode 100644
index 0000000..e2f8a74
--- /dev/null
+++ b/services/surfaceflinger/Android.mk
@@ -0,0 +1,56 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    clz.cpp.arm \
+    DisplayHardware/DisplayHardware.cpp \
+    DisplayHardware/DisplayHardwareBase.cpp \
+    BlurFilter.cpp.arm \
+    GLExtensions.cpp \
+    Layer.cpp \
+    LayerBase.cpp \
+    LayerBuffer.cpp \
+    LayerBlur.cpp \
+    LayerDim.cpp \
+    MessageQueue.cpp \
+    SurfaceFlinger.cpp \
+    TextureManager.cpp \
+    Transform.cpp
+
+LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+
+ifeq ($(TARGET_BOARD_PLATFORM), omap3)
+	LOCAL_CFLAGS += -DNO_RGBX_8888
+endif
+ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
+	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+endif
+
+
+# need "-lrt" on Linux simulator to pick up clock_gettime
+ifeq ($(TARGET_SIMULATOR),true)
+	ifeq ($(HOST_OS),linux)
+		LOCAL_LDLIBS += -lrt -lpthread
+	endif
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libpixelflinger \
+	libhardware \
+	libutils \
+	libEGL \
+	libGLESv1_CM \
+	libbinder \
+	libui \
+	libsurfaceflinger_client
+
+LOCAL_C_INCLUDES := \
+	$(call include-path-for, corecg graphics)
+
+LOCAL_C_INCLUDES += hardware/libhardware/modules/gralloc
+
+LOCAL_MODULE:= libsurfaceflinger
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/services/surfaceflinger/Barrier.h b/services/surfaceflinger/Barrier.h
new file mode 100644
index 0000000..6f8507e
--- /dev/null
+++ b/services/surfaceflinger/Barrier.h
@@ -0,0 +1,55 @@
+/*
+ * 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_BARRIER_H
+#define ANDROID_BARRIER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class Barrier
+{
+public:
+    inline Barrier() : state(CLOSED) { }
+    inline ~Barrier() { }
+    void open() {
+        Mutex::Autolock _l(lock);
+        state = OPENED;
+        cv.broadcast();
+    }
+    void close() {
+        Mutex::Autolock _l(lock);
+        state = CLOSED;
+    }
+    void wait() const {
+        Mutex::Autolock _l(lock);
+        while (state == CLOSED) {
+            cv.wait(lock);
+        }
+    }
+private:
+    enum { OPENED, CLOSED };
+    mutable     Mutex       lock;
+    mutable     Condition   cv;
+    volatile    int         state;
+};
+
+}; // namespace android
+
+#endif // ANDROID_BARRIER_H
diff --git a/libs/surfaceflinger/BlurFilter.cpp b/services/surfaceflinger/BlurFilter.cpp
similarity index 100%
rename from libs/surfaceflinger/BlurFilter.cpp
rename to services/surfaceflinger/BlurFilter.cpp
diff --git a/libs/surfaceflinger/BlurFilter.h b/services/surfaceflinger/BlurFilter.h
similarity index 100%
rename from libs/surfaceflinger/BlurFilter.h
rename to services/surfaceflinger/BlurFilter.h
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
new file mode 100644
index 0000000..28a512e
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -0,0 +1,350 @@
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#include <cutils/properties.h>
+
+#include <utils/RefBase.h>
+#include <utils/Log.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/EGLUtils.h>
+
+#include <GLES/gl.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "DisplayHardware/DisplayHardware.h"
+
+#include <hardware/copybit.h>
+#include <hardware/overlay.h>
+#include <hardware/gralloc.h>
+
+#include "GLExtensions.h"
+
+using namespace android;
+
+
+static __attribute__((noinline))
+void checkGLErrors()
+{
+    do {
+        // there could be more than one error flag
+        GLenum error = glGetError();
+        if (error == GL_NO_ERROR)
+            break;
+        LOGE("GL error 0x%04x", int(error));
+    } while(true);
+}
+
+static __attribute__((noinline))
+void checkEGLErrors(const char* token)
+{
+    EGLint error = eglGetError();
+    if (error && error != EGL_SUCCESS) {
+        LOGE("%s: EGL error 0x%04x (%s)",
+                token, int(error), EGLUtils::strerror(error));
+    }
+}
+
+/*
+ * Initialize the display to the specified values.
+ *
+ */
+
+DisplayHardware::DisplayHardware(
+        const sp<SurfaceFlinger>& flinger,
+        uint32_t dpy)
+    : DisplayHardwareBase(flinger, dpy),
+      mFlags(0)
+{
+    init(dpy);
+}
+
+DisplayHardware::~DisplayHardware()
+{
+    fini();
+}
+
+float DisplayHardware::getDpiX() const          { return mDpiX; }
+float DisplayHardware::getDpiY() const          { return mDpiY; }
+float DisplayHardware::getDensity() const       { return mDensity; }
+float DisplayHardware::getRefreshRate() const   { return mRefreshRate; }
+int DisplayHardware::getWidth() const           { return mWidth; }
+int DisplayHardware::getHeight() const          { return mHeight; }
+PixelFormat DisplayHardware::getFormat() const  { return mFormat; }
+uint32_t DisplayHardware::getMaxTextureSize() const { return mMaxTextureSize; }
+uint32_t DisplayHardware::getMaxViewportDims() const { return mMaxViewportDims; }
+
+void DisplayHardware::init(uint32_t dpy)
+{
+    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;
+    if (hw_get_module(OVERLAY_HARDWARE_MODULE_ID, &module) == 0) {
+        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,
+            EGL_NONE,           0,
+            EGL_NONE
+    };
+
+    // debug: disable h/w rendering
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("debug.sf.hw", property, NULL) > 0) {
+        if (atoi(property) == 0) {
+            LOGW("H/W composition disabled");
+            attribs[2] = EGL_CONFIG_CAVEAT;
+            attribs[3] = EGL_SLOW_CONFIG;
+        }
+    }
+
+    // TODO: all the extensions below should be queried through
+    // eglGetProcAddress().
+
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(display, NULL, NULL);
+    eglGetConfigs(display, NULL, 0, &numConfigs);
+
+    EGLConfig config;
+    status_t err = EGLUtils::selectConfigForNativeWindow(
+            display, attribs, mNativeWindow.get(), &config);
+    LOGE_IF(err, "couldn't find an EGLConfig matching the screen format");
+    
+    EGLint r,g,b,a;
+    eglGetConfigAttrib(display, config, EGL_RED_SIZE,   &r);
+    eglGetConfigAttrib(display, config, EGL_GREEN_SIZE, &g);
+    eglGetConfigAttrib(display, config, EGL_BLUE_SIZE,  &b);
+    eglGetConfigAttrib(display, config, EGL_ALPHA_SIZE, &a);
+
+    if (mNativeWindow->isUpdateOnDemand()) {
+        mFlags |= PARTIAL_UPDATES;
+    }
+    
+    if (eglGetConfigAttrib(display, config, EGL_CONFIG_CAVEAT, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_SLOW_CONFIG)
+            mFlags |= SLOW_CONFIG;
+    }
+
+    /*
+     * Create our main surface
+     */
+
+    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
+        // preserve the backbuffer, which may be costly.
+        eglSurfaceAttrib(display, surface,
+                EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
+    }
+
+    if (eglQuerySurface(display, surface, EGL_SWAP_BEHAVIOR, &dummy) == EGL_TRUE) {
+        if (dummy == EGL_BUFFER_PRESERVED) {
+            mFlags |= BUFFER_PRESERVED;
+        }
+    }
+    
+    /* Read density from build-specific ro.sf.lcd_density property
+     * except if it is overridden by qemu.sf.lcd_density.
+     */
+    if (property_get("qemu.sf.lcd_density", property, NULL) <= 0) {
+        if (property_get("ro.sf.lcd_density", property, NULL) <= 0) {
+            LOGW("ro.sf.lcd_density not defined, using 160 dpi by default.");
+            strcpy(property, "160");
+        }
+    } else {
+        /* for the emulator case, reset the dpi values too */
+        mDpiX = mDpiY = atoi(property);
+    }
+    mDensity = atoi(property) * (1.0f/160.0f);
+
+
+    /*
+     * Create our OpenGL ES context
+     */
+    
+
+    EGLint contextAttributes[] = {
+#ifdef EGL_IMG_context_priority
+#ifdef HAS_CONTEXT_PRIORITY
+#warning "using EGL_IMG_context_priority"
+        EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG,
+#endif
+#endif
+        EGL_NONE, EGL_NONE
+    };
+    context = eglCreateContext(display, config, NULL, contextAttributes);
+
+    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);
+}
+
+/*
+ * Clean up.  Throw out our local state.
+ *
+ * (It's entirely possible we'll never get here, since this is meant
+ * for real hardware, which doesn't restart.)
+ */
+
+void DisplayHardware::fini()
+{
+    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+    eglTerminate(mDisplay);
+    overlay_control_close(mOverlayEngine);
+}
+
+void DisplayHardware::releaseScreen() const
+{
+    DisplayHardwareBase::releaseScreen();
+}
+
+void DisplayHardware::acquireScreen() const
+{
+    DisplayHardwareBase::acquireScreen();
+}
+
+uint32_t DisplayHardware::getPageFlipCount() const {
+    return mPageFlipCount;
+}
+
+status_t DisplayHardware::compositionComplete() const {
+    return mNativeWindow->compositionComplete();
+}
+
+int DisplayHardware::getCurrentBufferIndex() const {
+    return mNativeWindow->getCurrentBufferIndex();
+}
+
+void DisplayHardware::flip(const Region& dirty) const
+{
+    checkGLErrors();
+
+    EGLDisplay dpy = mDisplay;
+    EGLSurface surface = mSurface;
+
+#ifdef EGL_ANDROID_swap_rectangle    
+    if (mFlags & SWAP_RECTANGLE) {
+        const Region newDirty(dirty.intersect(bounds()));
+        const Rect b(newDirty.getBounds());
+        eglSetSwapRectangleANDROID(dpy, surface,
+                b.left, b.top, b.width(), b.height());
+    } 
+#endif
+    
+    if (mFlags & PARTIAL_UPDATES) {
+        mNativeWindow->setUpdateRectangle(dirty.getBounds());
+    }
+    
+    mPageFlipCount++;
+    eglSwapBuffers(dpy, surface);
+    checkEGLErrors("eglSwapBuffers");
+
+    // for debugging
+    //glClearColor(1,0,0,0);
+    //glClear(GL_COLOR_BUFFER_BIT);
+}
+
+uint32_t DisplayHardware::getFlags() const
+{
+    return mFlags;
+}
+
+void DisplayHardware::makeCurrent() const
+{
+    eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
+}
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardware.h b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
new file mode 100644
index 0000000..2d7900c
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.h
@@ -0,0 +1,119 @@
+/*
+ * 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_DISPLAY_HARDWARE_H
+#define ANDROID_DISPLAY_HARDWARE_H
+
+#include <stdlib.h>
+
+#include <ui/PixelFormat.h>
+#include <ui/Region.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "GLExtensions.h"
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+
+struct overlay_control_device_t;
+struct framebuffer_device_t;
+struct copybit_image_t;
+
+namespace android {
+
+class FramebufferNativeWindow;
+
+class DisplayHardware : public DisplayHardwareBase
+{
+public:
+    enum {
+        COPY_BITS_EXTENSION         = 0x00000008,
+        BUFFER_PRESERVED            = 0x00010000,
+        PARTIAL_UPDATES             = 0x00020000,   // video driver feature
+        SLOW_CONFIG                 = 0x00040000,   // software
+        SWAP_RECTANGLE              = 0x00080000,
+    };
+
+    DisplayHardware(
+            const sp<SurfaceFlinger>& flinger,
+            uint32_t displayIndex);
+
+    ~DisplayHardware();
+
+    void releaseScreen() const;
+    void acquireScreen() const;
+
+    // Flip the front and back buffers if the back buffer is "dirty".  Might
+    // be instantaneous, might involve copying the frame buffer around.
+    void flip(const Region& dirty) const;
+
+    float       getDpiX() const;
+    float       getDpiY() const;
+    float       getRefreshRate() const;
+    float       getDensity() const;
+    int         getWidth() const;
+    int         getHeight() const;
+    PixelFormat getFormat() const;
+    uint32_t    getFlags() const;
+    void        makeCurrent() const;
+    uint32_t    getMaxTextureSize() const;
+    uint32_t    getMaxViewportDims() const;
+
+    uint32_t getPageFlipCount() const;
+    EGLDisplay getEGLDisplay() const { return mDisplay; }
+    overlay_control_device_t* getOverlayEngine() const { return mOverlayEngine; }
+    
+    status_t compositionComplete() const;
+    
+    Rect bounds() const {
+        return Rect(mWidth, mHeight);
+    }
+
+    // only for debugging
+    int getCurrentBufferIndex() const;
+
+private:
+    void init(uint32_t displayIndex) __attribute__((noinline));
+    void fini() __attribute__((noinline));
+
+    EGLDisplay      mDisplay;
+    EGLSurface      mSurface;
+    EGLContext      mContext;
+    EGLConfig       mConfig;
+    float           mDpiX;
+    float           mDpiY;
+    float           mRefreshRate;
+    float           mDensity;
+    int             mWidth;
+    int             mHeight;
+    PixelFormat     mFormat;
+    uint32_t        mFlags;
+    mutable uint32_t mPageFlipCount;
+    GLint           mMaxViewportDims;
+    GLint           mMaxTextureSize;
+    
+    sp<FramebufferNativeWindow> mNativeWindow;
+    overlay_control_device_t* mOverlayEngine;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_H
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
new file mode 100644
index 0000000..90865da
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
@@ -0,0 +1,408 @@
+/*
+ * 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 <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+
+#include <linux/unistd.h>
+
+#include <utils/Log.h>
+
+#include "DisplayHardware/DisplayHardwareBase.h"
+#include "SurfaceFlinger.h"
+
+// ----------------------------------------------------------------------------
+// the sim build doesn't have gettid
+
+#ifndef HAVE_GETTID
+# define gettid getpid
+#endif
+
+// ----------------------------------------------------------------------------
+namespace android {
+
+static char const * kSleepFileName = "/sys/power/wait_for_fb_sleep";
+static char const * kWakeFileName = "/sys/power/wait_for_fb_wake";
+static char const * const kOldSleepFileName = "/sys/android_power/wait_for_fb_sleep";
+static char const * const kOldWakeFileName = "/sys/android_power/wait_for_fb_wake";
+
+// This dir exists if the framebuffer console is present, either built into
+// the kernel or loaded as a module.
+static char const * const kFbconSysDir = "/sys/class/graphics/fbcon";
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThreadBase::DisplayEventThreadBase(
+        const sp<SurfaceFlinger>& flinger)
+    : Thread(false), mFlinger(flinger) {
+}
+
+DisplayHardwareBase::DisplayEventThreadBase::~DisplayEventThreadBase() {
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayEventThread::DisplayEventThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger)
+{
+}
+
+DisplayHardwareBase::DisplayEventThread::~DisplayEventThread()
+{
+}
+
+bool DisplayHardwareBase::DisplayEventThread::threadLoop()
+{
+    int err = 0;
+    char buf;
+    int fd;
+
+    fd = open(kSleepFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_SLEEP failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0) {
+            mBarrier.close();
+            flinger->screenReleased(0);
+            mBarrier.wait();
+        }
+    }
+    fd = open(kWakeFileName, O_RDONLY, 0);
+    do {
+      err = read(fd, &buf, 1);
+    } while (err < 0 && errno == EINTR);
+    close(fd);
+    LOGW_IF(err<0, "ANDROID_WAIT_FOR_FB_WAKE failed (%s)", strerror(errno));
+    if (err >= 0) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenAcquired(0);
+    }
+    return true;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::releaseScreen() const
+{
+    mBarrier.open();
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::readyToRun()
+{
+    if (access(kSleepFileName, R_OK) || access(kWakeFileName, R_OK)) {
+        if (access(kOldSleepFileName, R_OK) || access(kOldWakeFileName, R_OK)) {
+            LOGE("Couldn't open %s or %s", kSleepFileName, kWakeFileName);
+            return NO_INIT;
+        }
+        kSleepFileName = kOldSleepFileName;
+        kWakeFileName = kOldWakeFileName;
+    }
+    return NO_ERROR;
+}
+
+status_t DisplayHardwareBase::DisplayEventThread::initCheck() const
+{
+    return (((access(kSleepFileName, R_OK) == 0 &&
+            access(kWakeFileName, R_OK) == 0) ||
+            (access(kOldSleepFileName, R_OK) == 0 &&
+            access(kOldWakeFileName, R_OK) == 0)) &&
+            access(kFbconSysDir, F_OK) != 0) ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+pid_t DisplayHardwareBase::ConsoleManagerThread::sSignalCatcherPid = 0;
+
+DisplayHardwareBase::ConsoleManagerThread::ConsoleManagerThread(
+        const sp<SurfaceFlinger>& flinger)
+    : DisplayEventThreadBase(flinger), consoleFd(-1)
+{   
+    sSignalCatcherPid = 0;
+
+    // create a new console
+    char const * const ttydev = "/dev/tty0";
+    int fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // to make sure that we are in text mode
+    int res = ioctl(fd, KDSETMODE, (void*) KD_TEXT);
+    if (res<0) {
+        LOGE("ioctl(%d, KDSETMODE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+    }
+    
+    // get the current console
+    struct vt_stat vs;
+    res = ioctl(fd, VT_GETSTATE, &vs);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_GETSTATE, ...) failed, res %d (%s)",
+                fd, res, strerror(errno));
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // switch to console 7 (which is what X normaly uses)
+    int vtnum = 7;
+    do {
+        res = ioctl(fd, VT_ACTIVATE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_ACTIVATE, ...) failed, %d (%s) for %d",
+                fd, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    do {
+        res = ioctl(fd, VT_WAITACTIVE, (void*)vtnum);
+    } while(res < 0 && errno == EINTR);
+    if (res<0) {
+        LOGE("ioctl(%d, VT_WAITACTIVE, ...) failed, %d %d %s for %d",
+                fd, res, errno, strerror(errno), vtnum);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    // open the new console
+    close(fd);
+    fd = open(ttydev, O_RDWR | O_SYNC);
+    if (fd<0) {
+        LOGE("Can't open new console %s", ttydev);
+        this->consoleFd = -errno;
+        return;
+    }
+
+    /* disable console line buffer, echo, ... */
+    struct termios ttyarg;
+    ioctl(fd, TCGETS , &ttyarg);
+    ttyarg.c_iflag = 0;
+    ttyarg.c_lflag = 0;
+    ioctl(fd, TCSETS , &ttyarg);
+
+    // set up signals so we're notified when the console changes
+    // we can't use SIGUSR1 because it's used by the java-vm
+    vm.mode = VT_PROCESS;
+    vm.waitv = 0;
+    vm.relsig = SIGUSR2;
+    vm.acqsig = SIGUNUSED;
+    vm.frsig = 0;
+
+    struct sigaction act;
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.relsig, &act, NULL);
+
+    sigemptyset(&act.sa_mask);
+    act.sa_handler = sigHandler;
+    act.sa_flags = 0;
+    sigaction(vm.acqsig, &act, NULL);
+
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+    sigprocmask(SIG_BLOCK, &mask, NULL);
+
+    // switch to graphic mode
+    res = ioctl(fd, KDSETMODE, (void*)KD_GRAPHICS);
+    LOGW_IF(res<0,
+            "ioctl(%d, KDSETMODE, KD_GRAPHICS) failed, res %d", fd, res);
+
+    this->prev_vt_num = vs.v_active;
+    this->vt_num = vtnum;
+    this->consoleFd = fd;
+}
+
+DisplayHardwareBase::ConsoleManagerThread::~ConsoleManagerThread()
+{   
+    if (this->consoleFd >= 0) {
+        int fd = this->consoleFd;
+        int prev_vt_num = this->prev_vt_num;
+        int res;
+        ioctl(fd, KDSETMODE, (void*)KD_TEXT);
+        do {
+            res = ioctl(fd, VT_ACTIVATE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        do {
+            res = ioctl(fd, VT_WAITACTIVE, (void*)prev_vt_num);
+        } while(res < 0 && errno == EINTR);
+        close(fd);    
+        char const * const ttydev = "/dev/tty0";
+        fd = open(ttydev, O_RDWR | O_SYNC);
+        ioctl(fd, VT_DISALLOCATE, 0);
+        close(fd);
+    }
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::readyToRun()
+{
+    if (this->consoleFd >= 0) {
+        sSignalCatcherPid = gettid();
+        
+        sigset_t mask;
+        sigemptyset(&mask);
+        sigaddset(&mask, vm.relsig);
+        sigaddset(&mask, vm.acqsig);
+        sigprocmask(SIG_BLOCK, &mask, NULL);
+
+        int res = ioctl(this->consoleFd, VT_SETMODE, &vm);
+        if (res<0) {
+            LOGE("ioctl(%d, VT_SETMODE, ...) failed, %d (%s)",
+                    this->consoleFd, errno, strerror(errno));
+        }
+        return NO_ERROR;
+    }
+    return this->consoleFd;
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::requestExit()
+{
+    Thread::requestExit();
+    if (sSignalCatcherPid != 0) {
+        // wake the thread up
+        kill(sSignalCatcherPid, SIGINT);
+        // wait for it...
+    }
+}
+
+void DisplayHardwareBase::ConsoleManagerThread::sigHandler(int sig)
+{
+    // resend the signal to our signal catcher thread
+    LOGW("received signal %d in thread %d, resending to %d",
+            sig, gettid(), sSignalCatcherPid);
+
+    // we absolutely need the delays below because without them
+    // our main thread never gets a chance to handle the signal.
+    usleep(10000);
+    kill(sSignalCatcherPid, sig);
+    usleep(10000);
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::releaseScreen() const
+{
+    int fd = this->consoleFd;
+    int err = ioctl(fd, VT_RELDISP, (void*)1);
+    LOGE_IF(err<0, "ioctl(%d, VT_RELDISP, 1) failed %d (%s)",
+        fd, errno, strerror(errno));
+    return (err<0) ? (-errno) : status_t(NO_ERROR);
+}
+
+bool DisplayHardwareBase::ConsoleManagerThread::threadLoop()
+{
+    sigset_t mask;
+    sigemptyset(&mask);
+    sigaddset(&mask, vm.relsig);
+    sigaddset(&mask, vm.acqsig);
+
+    int sig = 0;
+    sigwait(&mask, &sig);
+
+    if (sig == vm.relsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("About to give-up screen, flinger = %p", flinger.get());
+        if (flinger != 0)
+            flinger->screenReleased(0);
+    } else if (sig == vm.acqsig) {
+        sp<SurfaceFlinger> flinger = mFlinger.promote();
+        //LOGD("Screen about to return, flinger = %p", flinger.get());
+        if (flinger != 0) 
+            flinger->screenAcquired(0);
+    }
+    
+    return true;
+}
+
+status_t DisplayHardwareBase::ConsoleManagerThread::initCheck() const
+{
+    return consoleFd >= 0 ? NO_ERROR : NO_INIT;
+}
+
+// ----------------------------------------------------------------------------
+
+DisplayHardwareBase::DisplayHardwareBase(const sp<SurfaceFlinger>& flinger,
+        uint32_t displayIndex) 
+    : mCanDraw(true), mScreenAcquired(true)
+{
+    mDisplayEventThread = new DisplayEventThread(flinger);
+    if (mDisplayEventThread->initCheck() != NO_ERROR) {
+        // fall-back on the console
+        mDisplayEventThread = new ConsoleManagerThread(flinger);
+    }
+}
+
+DisplayHardwareBase::~DisplayHardwareBase()
+{
+    // request exit
+    mDisplayEventThread->requestExitAndWait();
+}
+
+void DisplayHardwareBase::setCanDraw(bool canDraw)
+{
+    mCanDraw = canDraw;
+}
+
+bool DisplayHardwareBase::canDraw() const
+{
+    return mCanDraw && mScreenAcquired;
+}
+
+void DisplayHardwareBase::releaseScreen() const
+{
+    status_t err = mDisplayEventThread->releaseScreen();
+    if (err >= 0) {
+        mScreenAcquired = false;
+    }
+}
+
+void DisplayHardwareBase::acquireScreen() const
+{
+    status_t err = mDisplayEventThread->acquireScreen();
+    if (err >= 0) {
+        mScreenAcquired = true;
+    }
+}
+
+bool DisplayHardwareBase::isScreenAcquired() const
+{
+    return mScreenAcquired;
+}
+
+}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
new file mode 100644
index 0000000..fa6a0c4
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.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_DISPLAY_HARDWARE_BASE_H
+#define ANDROID_DISPLAY_HARDWARE_BASE_H
+
+#include <stdint.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include "Barrier.h"
+
+namespace android {
+
+class SurfaceFlinger; 
+
+class DisplayHardwareBase
+{
+public:
+                DisplayHardwareBase(
+                        const sp<SurfaceFlinger>& flinger,
+                        uint32_t displayIndex);
+
+                ~DisplayHardwareBase();
+
+    // console managment
+    void releaseScreen() const;
+    void acquireScreen() const;
+    bool isScreenAcquired() const;
+
+    bool canDraw() const;
+    void setCanDraw(bool canDraw);
+
+
+private:
+    class DisplayEventThreadBase : public Thread {
+    protected:
+        wp<SurfaceFlinger> mFlinger;
+    public:
+        DisplayEventThreadBase(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThreadBase();
+        virtual void onFirstRef() {
+            run("DisplayEventThread", PRIORITY_URGENT_DISPLAY);
+        }
+        virtual status_t acquireScreen() const { return NO_ERROR; };
+        virtual status_t releaseScreen() const { return NO_ERROR; };
+        virtual status_t initCheck() const = 0;
+    };
+
+    class DisplayEventThread : public DisplayEventThreadBase 
+    {
+        mutable Barrier mBarrier;
+    public:
+                DisplayEventThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~DisplayEventThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    class ConsoleManagerThread : public DisplayEventThreadBase 
+    {
+        int consoleFd;
+        int vt_num;
+        int prev_vt_num;
+        vt_mode vm;
+        static void sigHandler(int sig);
+        static pid_t sSignalCatcherPid;
+    public:
+                ConsoleManagerThread(const sp<SurfaceFlinger>& flinger);
+        virtual ~ConsoleManagerThread();
+        virtual bool threadLoop();
+        virtual status_t readyToRun();
+        virtual void requestExit();
+        virtual status_t releaseScreen() const;
+        virtual status_t initCheck() const;
+    };
+
+    sp<DisplayEventThreadBase>  mDisplayEventThread;
+    mutable int                 mCanDraw;
+    mutable int                 mScreenAcquired;
+};
+
+}; // namespace android
+
+#endif // ANDROID_DISPLAY_HARDWARE_BASE_H
diff --git a/services/surfaceflinger/GLExtensions.cpp b/services/surfaceflinger/GLExtensions.cpp
new file mode 100644
index 0000000..493122d
--- /dev/null
+++ b/services/surfaceflinger/GLExtensions.cpp
@@ -0,0 +1,137 @@
+/*
+ * 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_EGL_image_external")) {
+        mHaveTextureExternal = true;
+    } else if (strstr(mRenderer.string(), "Adreno")) {
+        // hack for Adreno 200
+        mHaveTextureExternal = true;
+    }
+
+    if (hasExtension("GL_OES_framebuffer_object")) {
+        mHaveFramebufferObject = 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..c86c66a
--- /dev/null
+++ b/services/surfaceflinger/GLExtensions.h
@@ -0,0 +1,99 @@
+/*
+ * 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;
+    bool mHaveFramebufferObject : 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;
+    }
+
+    inline bool haveFramebufferObject() const {
+        return mHaveFramebufferObject;
+    }
+
+    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
new file mode 100644
index 0000000..a060d31
--- /dev/null
+++ b/services/surfaceflinger/Layer.cpp
@@ -0,0 +1,891 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <cutils/properties.h>
+#include <cutils/native_handle.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+
+#include <surfaceflinger/Surface.h>
+
+#include "clz.h"
+#include "GLExtensions.h"
+#include "Layer.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+
+#define DEBUG_RESIZE    0
+
+
+namespace android {
+
+template <typename T> inline T min(T a, T b) {
+    return a<b ? a : b;
+}
+
+// ---------------------------------------------------------------------------
+
+Layer::Layer(SurfaceFlinger* flinger,
+        DisplayID display, const sp<Client>& client)
+    :   LayerBaseClient(flinger, display, client),
+        mGLExtensions(GLExtensions::getInstance()),
+        mNeedsBlending(true),
+        mNeedsDithering(false),
+        mSecure(false),
+        mTextureManager(),
+        mBufferManager(mTextureManager),
+        mWidth(0), mHeight(0), mFixedSize(false)
+{
+}
+
+Layer::~Layer()
+{
+    // 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);
+    }
+}
+
+status_t Layer::setToken(const sp<UserClient>& userClient,
+        SharedClient* sharedClient, int32_t token)
+{
+    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
+    }
+
+    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
+{
+    return mSurface;
+}
+
+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();
+
+    EGLDisplay dpy(mFlinger->graphicPlane(0).getEGLDisplay());
+    mBufferManager.destroy(dpy);
+    mSurface.clear();
+
+    Mutex::Autolock _l(mLock);
+    mWidth = mHeight = 0;
+    return NO_ERROR;
+}
+
+status_t Layer::setBuffers( uint32_t w, uint32_t h,
+                            PixelFormat format, uint32_t flags)
+{
+    // this surfaces pixel format
+    PixelFormatInfo info;
+    status_t err = getPixelFormatInfo(format, &info);
+    if (err) return err;
+
+    // the display's pixel format
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    uint32_t const maxSurfaceDims = min(
+            hw.getMaxTextureSize(), hw.getMaxViewportDims());
+
+    // never allow a surface larger than what our underlying GL implementation
+    // can handle.
+    if ((uint32_t(w)>maxSurfaceDims) || (uint32_t(h)>maxSurfaceDims)) {
+        return BAD_VALUE;
+    }
+
+    PixelFormatInfo displayInfo;
+    getPixelFormatInfo(hw.getFormat(), &displayInfo);
+    const uint32_t hwFlags = hw.getFlags();
+    
+    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;
+
+    // we use the red index
+    int displayRedSize = displayInfo.getSize(PixelFormatInfo::INDEX_RED);
+    int layerRedsize = info.getSize(PixelFormatInfo::INDEX_RED);
+    mNeedsDithering = layerRedsize > displayRedSize;
+
+    mSurface = new SurfaceLayer(mFlinger, this);
+    return NO_ERROR;
+}
+
+void Layer::reloadTexture(const Region& dirty)
+{
+    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
+        // to this context.
+        return;
+    }
+
+    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) {
+                mBufferManager.loadTexture(dirty, t);
+                buffer->unlock();
+            }
+        } else {
+            // we can't do anything
+        }
+    }
+}
+
+void Layer::drawForSreenShot() const
+{
+    bool currentFixedSize = mFixedSize;
+    bool currentBlending = mNeedsBlending;
+    const_cast<Layer*>(this)->mFixedSize = false;
+    const_cast<Layer*>(this)->mFixedSize = true;
+    LayerBase::drawForSreenShot();
+    const_cast<Layer*>(this)->mFixedSize = currentFixedSize;
+    const_cast<Layer*>(this)->mNeedsBlending = currentBlending;
+}
+
+void Layer::onDraw(const Region& clip) const
+{
+    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
+        // has drawn the first time.
+
+        // If there is nothing under us, we paint the screen in black, otherwise
+        // we just skip this update.
+
+        // figure out if there is something below us
+        Region under;
+        const SurfaceFlinger::LayerVector& drawingLayers(mFlinger->mDrawingState.layersSortedByZ);
+        const size_t count = drawingLayers.size();
+        for (size_t i=0 ; i<count ; ++i) {
+            const sp<LayerBase>& layer(drawingLayers[i]);
+            if (layer.get() == static_cast<LayerBase const*>(this))
+                break;
+            under.orSelf(layer->visibleRegionScreen);
+        }
+        // if not everything below us is covered, we plug the holes!
+        Region holes(clip.subtract(under));
+        if (!holes.isEmpty()) {
+            clearWithOpenGL(holes, 0, 0, 0, 1);
+        }
+        return;
+    }
+    drawWithOpenGL(clip, tex);
+}
+
+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.
+    ClientRef::Access sharedClient(mUserClientRef);
+    SharedBufferServer* lcblk(sharedClient.get());
+    if (!lcblk) {
+        // oops, the client is already gone
+        return buffer;
+    }
+
+    /*
+     * 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.
+     */
+
+    status_t err = NO_ERROR;
+    uint32_t w, h, f;
+    { // scope for the lock
+        Mutex::Autolock _l(mLock);
+
+        // 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);
+    buffer = new GraphicBuffer(w, h, f, effectiveUsage);
+    err = buffer->initCheck();
+
+    if (err || buffer->handle == 0) {
+        LOGE_IF(err || buffer->handle == 0,
+                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d failed (%s)",
+                this, index, w, h, strerror(-err));
+    } else {
+        LOGD_IF(DEBUG_RESIZE,
+                "Layer::requestBuffer(this=%p), index=%d, w=%d, h=%d, handle=%p",
+                this, index, w, h, buffer->handle);
+    }
+
+    if (err == NO_ERROR && buffer->handle != 0) {
+        Mutex::Autolock _l(mLock);
+        mBufferManager.attachBuffer(index, buffer);
+    }
+    return buffer;
+}
+
+uint32_t Layer::getEffectiveUsage(uint32_t usage) const
+{
+    /*
+     *  buffers used for software rendering, but h/w composition
+     *  are allocated with SW_READ_OFTEN | SW_WRITE_OFTEN | HW_TEXTURE
+     *
+     *  buffers used for h/w rendering and h/w composition
+     *  are allocated with  HW_RENDER | HW_TEXTURE
+     *
+     *  buffers used with h/w rendering and either NPOT or no egl_image_ext
+     *  are allocated with SW_READ_RARELY | HW_RENDER
+     *
+     */
+
+    if (mSecure) {
+        // secure buffer, don't store it into the GPU
+        usage = GraphicBuffer::USAGE_SW_READ_OFTEN |
+                GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+    } else {
+        // it's allowed to modify the usage flags here, but generally
+        // the requested flags should be honored.
+        // request EGLImage for all buffers
+        usage |= GraphicBuffer::USAGE_HW_TEXTURE;
+    }
+    return usage;
+}
+
+uint32_t Layer::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    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)",
+                this,
+                int(temp.requested_w), int(temp.requested_h),
+                int(front.requested_w), int(front.requested_h));
+
+        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);
+        }
+    }
+
+    if (temp.sequence != front.sequence) {
+        if (temp.flags & ISurfaceComposer::eLayerHidden || temp.alpha == 0) {
+            // this surface is now hidden, so it shouldn't hold a freeze lock
+            // (it may never redraw, which is fine if it is hidden)
+            mFreezeLock.clear();
+        }
+    }
+        
+    return LayerBase::doTransaction(flags);
+}
+
+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 == 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;
+    }
+
+    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
+    if (mBufferManager.setActiveBufferIndex(buf) < NO_ERROR) {
+        LOGE("retireAndLock() buffer index (%d) out of range", int(buf));
+        mPostedDirtyRegion.clear();
+        return;
+    }
+
+    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() );
+
+        // update the layer size and release freeze-lock
+        const Layer::State& front(drawingState());
+        if (newFrontBuffer->getWidth()  == front.requested_w &&
+            newFrontBuffer->getHeight() == front.requested_h)
+        {
+            if ((front.w != front.requested_w) ||
+                (front.h != front.requested_h))
+            {
+                // Here we pretend the transaction happened by updating the
+                // current and drawing states. Drawing state is only accessed
+                // in this thread, no need to have it locked
+                Layer::State& editDraw(mDrawingState);
+                editDraw.w = editDraw.requested_w;
+                editDraw.h = editDraw.requested_h;
+
+                // We also need to update the current state so that we don't
+                // end-up doing too much work during the next transaction.
+                // NOTE: We actually don't need hold the transaction lock here
+                // because State::w and State::h are only accessed from
+                // this thread
+                Layer::State& editTemp(currentState());
+                editTemp.w = editDraw.w;
+                editTemp.h = editDraw.h;
+
+                // recompute visible region
+                recomputeVisibleRegions = true;
+            }
+
+            // 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
+        // to normal the next time the app tries to draw into this buffer.
+        // meanwhile, pretend the screen didn't update.
+        mPostedDirtyRegion.clear();
+    }
+
+    if (lcblk->getQueuedCount()) {
+        // signal an event if we have more buffers waiting
+        mFlinger->signalEvent();
+    }
+
+    /* 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(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+    Region dirtyRegion(mPostedDirtyRegion);
+    if (!dirtyRegion.isEmpty()) {
+        mPostedDirtyRegion.clear();
+        // The dirty region is given in the layer's coordinate space
+        // transform the dirty region by the surface's transformation
+        // and the global transformation.
+        const Layer::State& s(drawingState());
+        const Transform tr(planeTransform * s.transform);
+        dirtyRegion = tr.transform(dirtyRegion);
+
+        // At this point, the dirty region is in screen space.
+        // Make sure it's constrained by the visible region (which
+        // is in screen space as well).
+        dirtyRegion.andSelf(visibleRegionScreen);
+        outDirtyRegion.orSelf(dirtyRegion);
+    }
+    if (visibleRegionScreen.isEmpty()) {
+        // an invisible layer should not hold a freeze-lock
+        // (because it may never be updated and therefore never release it)
+        mFreezeLock.clear();
+    }
+}
+
+void Layer::finishPageFlip()
+{
+    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,
+        const sp<Layer>& owner)
+    : Surface(flinger, owner->getIdentity(), owner)
+{
+}
+
+Layer::SurfaceLayer::~SurfaceLayer()
+{
+}
+
+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) {
+        /*
+         * 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;
+}
+
+// ---------------------------------------------------------------------------
+
+
+}; // namespace android
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
new file mode 100644
index 0000000..263c372
--- /dev/null
+++ b/services/surfaceflinger/Layer.h
@@ -0,0 +1,240 @@
+/*
+ * 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_LAYER_H
+#define ANDROID_LAYER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <pixelflinger/pixelflinger.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include "LayerBase.h"
+#include "Transform.h"
+#include "TextureManager.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class FreezeLock;
+class Client;
+class GLExtensions;
+class UserClient;
+
+// ---------------------------------------------------------------------------
+
+class Layer : public LayerBaseClient
+{
+public:
+            Layer(SurfaceFlinger* flinger, DisplayID display,
+                    const sp<Client>& client);
+
+    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);
+
+    // 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 drawForSreenShot() const;
+    virtual void onDraw(const Region& clip) const;
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    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) const {
+        return mBufferManager.getBuffer(i); }
+    // only for debugging
+    inline const sp<FreezeLock>&  getFreezeLock() const {
+        return mFreezeLock; }
+
+protected:
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
+private:
+    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);
+
+    // -----------------------------------------------------------------------
+
+    class SurfaceLayer : public LayerBaseClient::Surface {
+    public:
+        SurfaceLayer(const sp<SurfaceFlinger>& flinger, const sp<Layer>& owner);
+        ~SurfaceLayer();
+    private:
+        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;
+
+    // -----------------------------------------------------------------------
+
+    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;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_H
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
new file mode 100644
index 0000000..64eed4b
--- /dev/null
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -0,0 +1,659 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <hardware/hardware.h>
+
+#include "clz.h"
+#include "LayerBase.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+#include "TextureManager.h"
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+int32_t LayerBase::sSequence = 1;
+
+LayerBase::LayerBase(SurfaceFlinger* flinger, DisplayID display)
+    : dpy(display), contentDirty(false),
+      sequence(uint32_t(android_atomic_inc(&sSequence))),
+      mFlinger(flinger),
+      mNeedsFiltering(false),
+      mOrientation(0),
+      mLeft(0), mTop(0),
+      mTransactionFlags(0),
+      mPremultipliedAlpha(true), mName("unnamed"), mDebug(false),
+      mInvalidate(0)
+{
+    const DisplayHardware& hw(flinger->graphicPlane(0).displayHardware());
+    mFlags = hw.getFlags();
+    mBufferCrop.makeInvalid();
+    mBufferTransform = 0;
+}
+
+LayerBase::~LayerBase()
+{
+}
+
+void LayerBase::setName(const String8& name) {
+    mName = name;
+}
+
+String8 LayerBase::getName() const {
+    return mName;
+}
+
+const GraphicPlane& LayerBase::graphicPlane(int dpy) const
+{ 
+    return mFlinger->graphicPlane(dpy);
+}
+
+GraphicPlane& LayerBase::graphicPlane(int dpy)
+{
+    return mFlinger->graphicPlane(dpy); 
+}
+
+void LayerBase::initStates(uint32_t w, uint32_t h, uint32_t flags)
+{
+    uint32_t layerFlags = 0;
+    if (flags & ISurfaceComposer::eHidden)
+        layerFlags = ISurfaceComposer::eLayerHidden;
+
+    if (flags & ISurfaceComposer::eNonPremultiplied)
+        mPremultipliedAlpha = false;
+
+    mCurrentState.z             = 0;
+    mCurrentState.w             = w;
+    mCurrentState.h             = h;
+    mCurrentState.requested_w   = w;
+    mCurrentState.requested_h   = h;
+    mCurrentState.alpha         = 0xFF;
+    mCurrentState.flags         = layerFlags;
+    mCurrentState.sequence      = 0;
+    mCurrentState.transform.set(0, 0);
+
+    // drawing state & current state are identical
+    mDrawingState = mCurrentState;
+}
+
+void LayerBase::commitTransaction() {
+    mDrawingState = mCurrentState;
+}
+void LayerBase::forceVisibilityTransaction() {
+    // this can be called without SurfaceFlinger.mStateLock, but if we
+    // can atomically increment the sequence number, it doesn't matter.
+    android_atomic_inc(&mCurrentState.sequence);
+    requestTransaction();
+}
+bool LayerBase::requestTransaction() {
+    int32_t old = setTransactionFlags(eTransactionNeeded);
+    return ((old & eTransactionNeeded) == 0);
+}
+uint32_t LayerBase::getTransactionFlags(uint32_t flags) {
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+uint32_t LayerBase::setTransactionFlags(uint32_t flags) {
+    return android_atomic_or(flags, &mTransactionFlags);
+}
+
+bool LayerBase::setPosition(int32_t x, int32_t y) {
+    if (mCurrentState.transform.tx() == x && mCurrentState.transform.ty() == y)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(x, y);
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setLayer(uint32_t z) {
+    if (mCurrentState.z == z)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.z = z;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setSize(uint32_t w, uint32_t h) {
+    if (mCurrentState.requested_w == w && mCurrentState.requested_h == h)
+        return false;
+    mCurrentState.requested_w = w;
+    mCurrentState.requested_h = h;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setAlpha(uint8_t alpha) {
+    if (mCurrentState.alpha == alpha)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.alpha = alpha;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setMatrix(const layer_state_t::matrix22_t& matrix) {
+    mCurrentState.sequence++;
+    mCurrentState.transform.set(
+            matrix.dsdx, matrix.dsdy, matrix.dtdx, matrix.dtdy);
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setTransparentRegionHint(const Region& transparent) {
+    mCurrentState.sequence++;
+    mCurrentState.transparentRegion = transparent;
+    requestTransaction();
+    return true;
+}
+bool LayerBase::setFlags(uint8_t flags, uint8_t mask) {
+    const uint32_t newFlags = (mCurrentState.flags & ~mask) | (flags & mask);
+    if (mCurrentState.flags == newFlags)
+        return false;
+    mCurrentState.sequence++;
+    mCurrentState.flags = newFlags;
+    requestTransaction();
+    return true;
+}
+
+Rect LayerBase::visibleBounds() const
+{
+    return mTransformedBounds;
+}      
+
+void LayerBase::setVisibleRegion(const Region& visibleRegion) {
+    // always called from main thread
+    visibleRegionScreen = visibleRegion;
+}
+
+void LayerBase::setCoveredRegion(const Region& coveredRegion) {
+    // always called from main thread
+    coveredRegionScreen = coveredRegion;
+}
+
+uint32_t LayerBase::doTransaction(uint32_t flags)
+{
+    const Layer::State& front(drawingState());
+    const Layer::State& temp(currentState());
+
+    if ((front.requested_w != temp.requested_w) ||
+        (front.requested_h != temp.requested_h))  {
+        // resize the layer, set the physical size to the requested size
+        Layer::State& editTemp(currentState());
+        editTemp.w = temp.requested_w;
+        editTemp.h = temp.requested_h;
+    }
+
+    if ((front.w != temp.w) || (front.h != temp.h)) {
+        // invalidate and recompute the visible regions if needed
+        flags |= Layer::eVisibleRegion;
+    }
+
+    if (temp.sequence != front.sequence) {
+        // invalidate and recompute the visible regions if needed
+        flags |= eVisibleRegion;
+        this->contentDirty = true;
+
+        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)) {
+                mNeedsFiltering = true;
+            }
+        }
+    }
+
+    // Commit the transaction
+    commitTransaction();
+    return flags;
+}
+
+void LayerBase::validateVisibility(const Transform& planeTransform)
+{
+    const Layer::State& s(drawingState());
+    const Transform tr(planeTransform * s.transform);
+    const bool transformed = tr.transformed();
+   
+    uint32_t w = s.w;
+    uint32_t h = s.h;    
+    tr.transform(mVertices[0], 0, 0);
+    tr.transform(mVertices[1], 0, h);
+    tr.transform(mVertices[2], w, h);
+    tr.transform(mVertices[3], w, 0);
+    if (UNLIKELY(transformed)) {
+        // NOTE: here we could also punt if we have too many rectangles
+        // in the transparent region
+        if (tr.preserveRects()) {
+            // transform the transparent region
+            transparentRegionScreen = tr.transform(s.transparentRegion);
+        } else {
+            // transformation too complex, can't do the transparent region
+            // optimization.
+            transparentRegionScreen.clear();
+        }
+    } else {
+        transparentRegionScreen = s.transparentRegion;
+    }
+
+    // cache a few things...
+    mOrientation = tr.getOrientation();
+    mTransformedBounds = tr.makeBounds(w, h);
+    mLeft = tr.tx();
+    mTop  = tr.ty();
+}
+
+void LayerBase::lockPageFlip(bool& recomputeVisibleRegions)
+{
+}
+
+void LayerBase::unlockPageFlip(
+        const Transform& planeTransform, Region& outDirtyRegion)
+{
+    if ((android_atomic_and(~1, &mInvalidate)&1) == 1) {
+        outDirtyRegion.orSelf(visibleRegionScreen);
+    }
+}
+
+void LayerBase::finishPageFlip()
+{
+}
+
+void LayerBase::invalidate()
+{
+    if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
+        mFlinger->signalEvent();
+    }
+}
+
+void LayerBase::drawRegion(const Region& reg) const
+{
+    Region::const_iterator it = reg.begin();
+    Region::const_iterator const end = reg.end();
+    if (it != end) {
+        Rect r;
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        const int32_t fbWidth  = hw.getWidth();
+        const int32_t fbHeight = hw.getHeight();
+        const GLshort vertices[][2] = { { 0, 0 }, { fbWidth, 0 }, 
+                { fbWidth, fbHeight }, { 0, fbHeight }  };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+        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); 
+        }
+    }
+}
+
+void LayerBase::draw(const Region& clip) const
+{
+    // reset GL state
+    glEnable(GL_SCISSOR_TEST);
+
+    onDraw(clip);
+}
+
+void LayerBase::drawForSreenShot() const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    onDraw( Region(hw.bounds()) );
+}
+
+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();
+    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_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); 
+    }
+}
+
+void LayerBase::clearWithOpenGL(const Region& clip) const
+{
+    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());
+    const uint32_t fbHeight = hw.getHeight();
+    const State& s(drawingState());
+    
+    // bind our texture
+    TextureManager::activateTexture(texture, needsFiltering());
+    uint32_t width  = texture.width; 
+    uint32_t height = texture.height;
+
+    GLenum src = mPremultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
+    if (UNLIKELY(s.alpha < 0xFF)) {
+        const GLfloat alpha = s.alpha * (1.0f/255.0f);
+        if (mPremultipliedAlpha) {
+            glColor4f(alpha, alpha, alpha, alpha);
+        } else {
+            glColor4f(1, 1, 1, alpha);
+        }
+        glEnable(GL_BLEND);
+        glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        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);
+        if (needsBlending()) {
+            glEnable(GL_BLEND);
+            glBlendFunc(src, GL_ONE_MINUS_SRC_ALPHA);
+        } else {
+            glDisable(GL_BLEND);
+        }
+    }
+
+    /*
+     *  compute texture coordinates
+     *  here, we handle NPOT, cropping and buffer transformations
+     */
+
+    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);
+    }
+
+    /*
+     * For the buffer transformation, we apply the rotation last.
+     * Since we're transforming the texture-coordinates, we need
+     * to apply the inverse of the buffer transformation:
+     *   inverse( FLIP_V -> FLIP_H -> ROT_90 )
+     *   <=> inverse( ROT_90 * FLIP_H * FLIP_V )
+     *    =  inverse(FLIP_V) * inverse(FLIP_H) * inverse(ROT_90)
+     *    =  FLIP_V * FLIP_H * ROT_270
+     *   <=> ROT_270 -> FLIP_H -> FLIP_V
+     *
+     * The rotation is performed first, in the texture coordinate space.
+     *
+     */
+
+    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(vRT, vRB);
+    }
+    if (transform & HAL_TRANSFORM_FLIP_H) {
+        swap(vLT, vRT);
+        swap(vLB, vRB);
+    }
+
+    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_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());
+        glScissor(r.left, sy, r.width(), r.height());
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+void LayerBase::setBufferCrop(const Rect& crop) {
+    if (!crop.isEmpty()) {
+        mBufferCrop = crop;
+    }
+}
+
+void LayerBase::setBufferTransform(uint32_t transform) {
+    mBufferTransform = transform;
+}
+
+void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    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);
+}
+
+// ---------------------------------------------------------------------------
+
+int32_t LayerBaseClient::sIdentity = 1;
+
+LayerBaseClient::LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+        const sp<Client>& client)
+    : LayerBase(flinger, display), mClientRef(client),
+      mIdentity(uint32_t(android_atomic_inc(&sIdentity)))
+{
+}
+
+LayerBaseClient::~LayerBaseClient()
+{
+    sp<Client> c(mClientRef.promote());
+    if (c != 0) {
+        c->detachLayer(this);
+    }
+}
+
+sp<LayerBaseClient::Surface> LayerBaseClient::getSurface()
+{
+    sp<Surface> s;
+    Mutex::Autolock _l(mLock);
+    s = mClientSurface.promote();
+    if (s == 0) {
+        s = createSurface();
+        mClientSurface = s;
+    }
+    return s;
+}
+
+sp<LayerBaseClient::Surface> LayerBaseClient::createSurface() const
+{
+    return new Surface(mFlinger, mIdentity,
+            const_cast<LayerBaseClient *>(this));
+}
+
+void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
+{
+    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,
+        int identity,
+        const sp<LayerBaseClient>& owner) 
+    : mFlinger(flinger), mIdentity(identity), mOwner(owner)
+{
+}
+
+LayerBaseClient::Surface::~Surface() 
+{
+    /*
+     * This is a good place to clean-up all client resources 
+     */
+
+    // destroy client resources
+    sp<LayerBaseClient> layer = getOwner();
+    if (layer != 0) {
+        mFlinger->destroySurface(layer);
+    }
+}
+
+sp<LayerBaseClient> LayerBaseClient::Surface::getOwner() const {
+    sp<LayerBaseClient> owner(mOwner.promote());
+    return owner;
+}
+
+status_t LayerBaseClient::Surface::onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case REGISTER_BUFFERS:
+        case UNREGISTER_BUFFERS:
+        case CREATE_OVERLAY:
+        {
+            if (!mFlinger->mAccessSurfaceFlinger.checkCalling()) {
+                IPCThreadState* ipc = IPCThreadState::self();
+                const int pid = ipc->getCallingPid();
+                const int uid = ipc->getCallingUid();
+                LOGE("Permission Denial: "
+                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                return PERMISSION_DENIED;
+            }
+        }
+    }
+    return BnSurface::onTransact(code, data, reply, flags);
+}
+
+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) 
+{ 
+    return INVALID_OPERATION; 
+}
+
+void LayerBaseClient::Surface::postBuffer(ssize_t offset) 
+{
+}
+
+void LayerBaseClient::Surface::unregisterBuffers() 
+{
+}
+
+sp<OverlayRef> LayerBaseClient::Surface::createOverlay(
+        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
+{
+    return NULL;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
new file mode 100644
index 0000000..d688f65
--- /dev/null
+++ b/services/surfaceflinger/LayerBase.h
@@ -0,0 +1,339 @@
+/*
+ * 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_LAYER_BASE_H
+#define ANDROID_LAYER_BASE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+
+#include <utils/RefBase.h>
+
+#include <ui/Region.h>
+#include <ui/Overlay.h>
+
+#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <private/surfaceflinger/SharedBufferStack.h>
+#include <private/surfaceflinger/LayerState.h>
+
+#include <pixelflinger/pixelflinger.h>
+
+#include "Transform.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class DisplayHardware;
+class Client;
+class GraphicBuffer;
+class GraphicPlane;
+class LayerBaseClient;
+class SurfaceFlinger;
+class Texture;
+
+// ---------------------------------------------------------------------------
+
+class LayerBase : public RefBase
+{
+    static int32_t sSequence;
+
+public:
+            LayerBase(SurfaceFlinger* flinger, DisplayID display);
+
+    DisplayID           dpy;
+    mutable bool        contentDirty;
+            Region      visibleRegionScreen;
+            Region      transparentRegionScreen;
+            Region      coveredRegionScreen;
+            int32_t     sequence;
+            
+            struct State {
+                uint32_t        w;
+                uint32_t        h;
+                uint32_t        requested_w;
+                uint32_t        requested_h;
+                uint32_t        z;
+                uint8_t         alpha;
+                uint8_t         flags;
+                uint8_t         reserved[2];
+                int32_t         sequence;   // changes when visible regions can change
+                uint32_t        tint;
+                Transform       transform;
+                Region          transparentRegion;
+            };
+
+            void setName(const String8& name);
+            String8 getName() const;
+
+            // modify current state
+            bool setPosition(int32_t x, int32_t y);
+            bool setLayer(uint32_t z);
+            bool setSize(uint32_t w, uint32_t h);
+            bool setAlpha(uint8_t alpha);
+            bool setMatrix(const layer_state_t::matrix22_t& matrix);
+            bool setTransparentRegionHint(const Region& opaque);
+            bool setFlags(uint8_t flags, uint8_t mask);
+            
+            void commitTransaction();
+            bool requestTransaction();
+            void forceVisibilityTransaction();
+            
+            uint32_t getTransactionFlags(uint32_t flags);
+            uint32_t setTransactionFlags(uint32_t flags);
+            
+            Rect visibleBounds() const;
+            void drawRegion(const Region& reg) const;
+
+            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().
+     * Typically this method is not overridden, instead implement onDraw()
+     * to perform the actual drawing.  
+     */
+    virtual void draw(const Region& clip) const;
+    virtual void drawForSreenShot() const;
+    
+    /**
+     * onDraw - draws the surface.
+     */
+    virtual void onDraw(const Region& clip) const = 0;
+    
+    /**
+     * initStates - called just after construction
+     */
+    virtual void initStates(uint32_t w, uint32_t h, uint32_t flags);
+    
+    /**
+     * doTransaction - process the transaction. This is a good place to figure
+     * out which attributes of the surface have changed.
+     */
+    virtual uint32_t doTransaction(uint32_t transactionFlags);
+    
+    /**
+     * setVisibleRegion - called to set the new visible region. This gives
+     * a chance to update the new visible region or record the fact it changed.
+     */
+    virtual void setVisibleRegion(const Region& visibleRegion);
+    
+    /**
+     * setCoveredRegion - called when the covered region changes. The covered
+     * region corresponds to any area of the surface that is covered
+     * (transparently or not) by another surface.
+     */
+    virtual void setCoveredRegion(const Region& coveredRegion);
+
+    /**
+     * validateVisibility - cache a bunch of things
+     */
+    virtual void validateVisibility(const Transform& globalTransform);
+
+    /**
+     * lockPageFlip - called each time the screen is redrawn and returns whether
+     * the visible regions need to be recomputed (this is a fairly heavy
+     * operation, so this should be set only if needed). Typically this is used
+     * to figure out if the content or size of a surface has changed.
+     */
+    virtual void lockPageFlip(bool& recomputeVisibleRegions);
+    
+    /**
+     * unlockPageFlip - called each time the screen is redrawn. updates the
+     * final dirty region wrt the planeTransform.
+     * At this point, all visible regions, surface position and size, etc... are
+     * correct.
+     */
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    
+    /**
+     * finishPageFlip - called after all surfaces have drawn.
+     */
+    virtual void finishPageFlip();
+    
+    /**
+     * needsBlending - true if this surface needs blending
+     */
+    virtual bool needsBlending() const  { return false; }
+
+    /**
+     * needsDithering - true if this surface needs dithering
+     */
+    virtual bool needsDithering() const { return false; }
+
+    /**
+     * needsLinearFiltering - true if this surface needs filtering
+     */
+    virtual bool needsFiltering() const { return mNeedsFiltering; }
+
+    /**
+     * isSecure - true if this surface is secure, that is if it prevents
+     * screenshots or VNC servers.
+     */
+    virtual bool isSecure() const       { return false; }
+
+    /** Called from the main thread, when the surface is removed from the
+     * draw list */
+    virtual status_t ditch() { return NO_ERROR; }
+
+    /** called with the state lock when the surface is removed from the
+     *  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,
+    };
+
+
+    inline  const State&    drawingState() const    { return mDrawingState; }
+    inline  const State&    currentState() const    { return mCurrentState; }
+    inline  State&          currentState()          { return mCurrentState; }
+
+    int32_t  getOrientation() const { return mOrientation; }
+    int  tx() const             { return mLeft; }
+    int  ty() const             { return mTop; }
+    
+protected:
+    const GraphicPlane& graphicPlane(int dpy) const;
+          GraphicPlane& graphicPlane(int dpy);
+
+          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;
+          
+          // 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            mNeedsFiltering;
+                int32_t         mOrientation;
+                GLfloat         mVertices[4][2];
+                Rect            mTransformedBounds;
+                int             mLeft;
+                int             mTop;
+            
+                // these are protected by an external lock
+                State           mCurrentState;
+                State           mDrawingState;
+    volatile    int32_t         mTransactionFlags;
+
+                // don't change, don't need a lock
+                bool            mPremultipliedAlpha;
+                String8         mName;
+    mutable     bool            mDebug;
+
+
+                // atomic
+    volatile    int32_t         mInvalidate;
+                
+
+protected:
+    virtual ~LayerBase();
+
+private:
+    LayerBase(const LayerBase& rhs);
+};
+
+
+// ---------------------------------------------------------------------------
+
+class LayerBaseClient : public LayerBase
+{
+public:
+    class Surface;
+
+            LayerBaseClient(SurfaceFlinger* flinger, DisplayID display,
+                        const sp<Client>& client);
+    virtual ~LayerBaseClient();
+
+            sp<Surface> getSurface();
+    virtual sp<Surface> createSurface() const;
+    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  {
+    public:
+        int32_t getIdentity() const { return mIdentity; }
+        
+    protected:
+        Surface(const sp<SurfaceFlinger>& flinger, int identity,
+                const sp<LayerBaseClient>& owner);
+        virtual ~Surface();
+        virtual status_t onTransact(uint32_t code, const Parcel& data,
+                Parcel* reply, uint32_t flags);
+        sp<LayerBaseClient> getOwner() const;
+
+    private:
+        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();
+        virtual sp<OverlayRef> createOverlay(uint32_t w, uint32_t h,
+                int32_t format, int32_t orientation);
+
+    protected:
+        friend class LayerBaseClient;
+        sp<SurfaceFlinger>  mFlinger;
+        int32_t             mIdentity;
+        wp<LayerBaseClient> mOwner;
+    };
+
+    friend class Surface;
+
+protected:
+    virtual void dump(String8& result, char* scratch, size_t size) const;
+
+private:
+    mutable Mutex mLock;
+    mutable wp<Surface> mClientSurface;
+    const wp<Client> mClientRef;
+    // only read
+    const uint32_t mIdentity;
+    static int32_t sIdentity;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BASE_H
diff --git a/services/surfaceflinger/LayerBlur.cpp b/services/surfaceflinger/LayerBlur.cpp
new file mode 100644
index 0000000..4cfcfe3
--- /dev/null
+++ b/services/surfaceflinger/LayerBlur.cpp
@@ -0,0 +1,251 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include "clz.h"
+#include "BlurFilter.h"
+#include "LayerBlur.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+LayerBlur::LayerBlur(SurfaceFlinger* flinger, DisplayID display,
+        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)
+{
+}
+
+LayerBlur::~LayerBlur()
+{
+    if (mTextureName != -1U) {
+        glDeleteTextures(1, &mTextureName);
+    }
+}
+
+void LayerBlur::setVisibleRegion(const Region& visibleRegion)
+{
+    LayerBaseClient::setVisibleRegion(visibleRegion);
+    if (visibleRegionScreen.isEmpty()) {
+        if (mTextureName != -1U) {
+            // We're not visible, free the texture up.
+            glBindTexture(GL_TEXTURE_2D, 0);
+            glDeleteTextures(1, &mTextureName);
+            mTextureName = -1U;
+        }
+    }
+}
+
+uint32_t LayerBlur::doTransaction(uint32_t flags)
+{
+    // we're doing a transaction, refresh the cache!
+    if (!mFlinger->isFrozen()) {
+        mRefreshCache = true;
+        mCacheDirty = true;
+        flags |= eVisibleRegion;
+        this->contentDirty = true;
+    }
+    return LayerBase::doTransaction(flags);    
+}
+
+void LayerBlur::unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    if (UNLIKELY(!visibleRegionScreen.isEmpty())) {
+        // if anything visible below us is invalidated, the cache becomes dirty
+        if (!mCacheDirty && 
+                !visibleRegionScreen.intersect(outDirtyRegion).isEmpty()) {
+            mCacheDirty = true;
+        }
+        if (mCacheDirty) {
+            if (!mFlinger->isFrozen()) {
+                // update everything below us that is visible
+                outDirtyRegion.orSelf(visibleRegionScreen);
+                nsecs_t now = systemTime();
+                if ((now - mCacheAge) >= ms2ns(500)) {
+                    mCacheAge = now;
+                    mRefreshCache = true;
+                    mCacheDirty = false;
+                } else {
+                    if (!mAutoRefreshPending) {
+                        mFlinger->postMessageAsync(
+                                new MessageBase(MessageQueue::INVALIDATE),
+                                ms2ns(500));
+                        mAutoRefreshPending = true;
+                    }
+                }
+            }
+        }
+    }
+    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);
+}
+
+void LayerBlur::onDraw(const Region& clip) const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t fbHeight = hw.getHeight();
+    int x = mTransformedBounds.left;
+    int y = mTransformedBounds.top;
+    int w = mTransformedBounds.width();
+    int h = mTransformedBounds.height();
+    GLint X = x;
+    GLint Y = fbHeight - (y + h);
+    if (X < 0) {
+        w += X;
+        X = 0;
+    }
+    if (Y < 0) {
+        h += Y;
+        Y = 0;
+    }
+    if (w<0 || h<0) {
+        // we're outside of the framebuffer
+        return;
+    }
+
+    if (mTextureName == -1U) {
+        // create the texture name the first time
+        // can't do that in the ctor, because it runs in another thread.
+        glGenTextures(1, &mTextureName);
+        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat);
+        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType);
+        if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) {
+            mReadFormat = GL_RGBA;
+            mReadType = GL_UNSIGNED_BYTE;
+            mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888;
+        }
+    }
+
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
+    if (it != end) {
+#if defined(GL_OES_EGL_image_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
+        }
+#endif
+        glEnable(GL_TEXTURE_2D);
+        glBindTexture(GL_TEXTURE_2D, mTextureName);
+
+        if (mRefreshCache) {
+            mRefreshCache = false;
+            mAutoRefreshPending = false;
+
+            int32_t pixelSize = 4;
+            int32_t s = w;
+            if (mReadType == GL_UNSIGNED_SHORT_5_6_5) {
+                // allocate enough memory for 4-bytes (2 pixels) aligned data
+                s = (w + 1) & ~1;
+                pixelSize = 2;
+            }
+
+            uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize);
+
+            // This reads the frame-buffer, so a h/w GL would have to
+            // finish() its rendering first. we don't want to do that
+            // too often. Read data is 4-bytes aligned.
+            glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels);
+
+            // blur that texture.
+            GGLSurface bl;
+            bl.version = sizeof(GGLSurface);
+            bl.width = w;
+            bl.height = h;
+            bl.stride = s;
+            bl.format = mBlurFormat;
+            bl.data = (GGLubyte*)pixels;            
+            blurFilter(&bl, 8, 2);
+
+            if (GLExtensions::getInstance().haveNpot()) {
+                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
+                        mReadFormat, mReadType, pixels);
+                mWidthScale  = 1.0f / w;
+                mHeightScale =-1.0f / h;
+                mYOffset = 0;
+            } else {
+                GLuint tw = 1 << (31 - clz(w));
+                GLuint th = 1 << (31 - clz(h));
+                if (tw < GLuint(w)) tw <<= 1;
+                if (th < GLuint(h)) th <<= 1;
+                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0,
+                        mReadFormat, mReadType, NULL);
+                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 
+                        mReadFormat, mReadType, pixels);
+                mWidthScale  = 1.0f / tw;
+                mHeightScale =-1.0f / th;
+                mYOffset = th-h;
+            }
+
+            free((void*)pixels);
+        }
+
+        const State& s = drawingState();
+        if (UNLIKELY(s.alpha < 0xFF)) {
+            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);
+        } else {
+            glDisable(GL_BLEND);
+        }
+
+        if (mFlags & DisplayHardware::SLOW_CONFIG) {
+            glDisable(GL_DITHER);
+        } else {
+            glEnable(GL_DITHER);
+        }
+
+        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+        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);
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/LayerBlur.h b/services/surfaceflinger/LayerBlur.h
new file mode 100644
index 0000000..4c9ec64
--- /dev/null
+++ b/services/surfaceflinger/LayerBlur.h
@@ -0,0 +1,65 @@
+/*
+ * 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_LAYER_BLUR_H
+#define ANDROID_LAYER_BLUR_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/Region.h>
+
+#include "LayerBase.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class LayerBlur : public LayerBaseClient
+{
+public:    
+                LayerBlur(SurfaceFlinger* flinger, DisplayID display,
+                        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);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+private:
+            bool    mCacheDirty;
+    mutable bool    mRefreshCache;
+    mutable bool    mAutoRefreshPending;
+            nsecs_t mCacheAge;
+    mutable GLuint  mTextureName;
+    mutable GLfloat mWidthScale;
+    mutable GLfloat mHeightScale;
+    mutable GLfloat mYOffset;
+    mutable GLint   mReadFormat;
+    mutable GLint   mReadType;
+    mutable uint32_t mBlurFormat;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BLUR_H
diff --git a/services/surfaceflinger/LayerBuffer.cpp b/services/surfaceflinger/LayerBuffer.cpp
new file mode 100644
index 0000000..edc00f1
--- /dev/null
+++ b/services/surfaceflinger/LayerBuffer.cpp
@@ -0,0 +1,701 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <math.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+#include <utils/StopWatch.h>
+
+#include <ui/GraphicBuffer.h>
+#include <ui/PixelFormat.h>
+#include <ui/FramebufferNativeWindow.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#include <hardware/copybit.h>
+
+#include "LayerBuffer.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+gralloc_module_t const* LayerBuffer::sGrallocModule = 0;
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+        const sp<Client>& client)
+    : LayerBaseClient(flinger, display, client),
+      mNeedsBlending(false), mBlitEngine(0)
+{
+}
+
+LayerBuffer::~LayerBuffer()
+{
+    if (mBlitEngine) {
+        copybit_close(mBlitEngine);
+    }
+}
+
+void LayerBuffer::onFirstRef()
+{
+    LayerBaseClient::onFirstRef();
+    mSurface = new SurfaceLayerBuffer(mFlinger, this);
+
+    hw_module_t const* module = (hw_module_t const*)sGrallocModule;
+    if (!module) {
+        // NOTE: technically there is a race here, but it shouldn't
+        // cause any problem since hw_get_module() always returns
+        // the same value.
+        if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
+            sGrallocModule = (gralloc_module_t const *)module;
+        }
+    }
+
+    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
+        copybit_open(module, &mBlitEngine);
+    }
+}
+
+sp<LayerBaseClient::Surface> LayerBuffer::createSurface() const
+{
+    return mSurface;
+}
+
+status_t LayerBuffer::ditch()
+{
+    mSurface.clear();
+    return NO_ERROR;
+}
+
+bool LayerBuffer::needsBlending() const {
+    return mNeedsBlending;
+}
+
+void LayerBuffer::setNeedsBlending(bool blending) {
+    mNeedsBlending = blending;
+}
+
+void LayerBuffer::postBuffer(ssize_t offset)
+{
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->postBuffer(offset);
+}
+
+void LayerBuffer::unregisterBuffers()
+{
+    sp<Source> source(clearSource());
+    if (source != 0)
+        source->unregisterBuffers();
+}
+
+uint32_t LayerBuffer::doTransaction(uint32_t flags)
+{
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->onTransaction(flags);
+    uint32_t res = LayerBase::doTransaction(flags);
+    // we always want filtering for these surfaces
+    mNeedsFiltering = !(mFlags & DisplayHardware::SLOW_CONFIG);
+    return res;
+}
+
+void LayerBuffer::unlockPageFlip(const Transform& planeTransform,
+        Region& outDirtyRegion)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->onVisibilityResolved(planeTransform);
+    LayerBase::unlockPageFlip(planeTransform, outDirtyRegion);    
+}
+
+void LayerBuffer::validateVisibility(const Transform& globalTransform)
+{
+    sp<Source> source(getSource());
+    if (source != 0)
+        source->onvalidateVisibility(globalTransform);
+    LayerBase::validateVisibility(globalTransform);
+}
+
+void LayerBuffer::drawForSreenShot() const
+{
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    clearWithOpenGL( Region(hw.bounds()) );
+}
+
+void LayerBuffer::onDraw(const Region& clip) const
+{
+    sp<Source> source(getSource());
+    if (LIKELY(source != 0)) {
+        source->onDraw(clip);
+    } else {
+        clearWithOpenGL(clip);
+    }
+}
+
+void LayerBuffer::serverDestroy()
+{
+    sp<Source> source(clearSource());
+    if (source != 0) {
+        source->destroy();
+    }
+}
+
+/**
+ * This creates a "buffer" source for this surface
+ */
+status_t LayerBuffer::registerBuffers(const ISurface::BufferHeap& buffers)
+{
+    Mutex::Autolock _l(mLock);
+    if (mSource != 0)
+        return INVALID_OPERATION;
+
+    sp<BufferSource> source = new BufferSource(*this, buffers);
+
+    status_t result = source->getStatus();
+    if (result == NO_ERROR) {
+        mSource = source;
+    }
+    return result;
+}    
+
+/**
+ * This creates an "overlay" source for this surface
+ */
+sp<OverlayRef> LayerBuffer::createOverlay(uint32_t w, uint32_t h, int32_t f,
+        int32_t orientation)
+{
+    sp<OverlayRef> result;
+    Mutex::Autolock _l(mLock);
+    if (mSource != 0)
+        return result;
+
+    sp<OverlaySource> source = new OverlaySource(*this, &result, w, h, f, orientation);
+    if (result != 0) {
+        mSource = source;
+    }
+    return result;
+}
+
+sp<LayerBuffer::Source> LayerBuffer::getSource() const {
+    Mutex::Autolock _l(mLock);
+    return mSource;
+}
+
+sp<LayerBuffer::Source> LayerBuffer::clearSource() {
+    sp<Source> source;
+    Mutex::Autolock _l(mLock);
+    source = mSource;
+    mSource.clear();
+    return source;
+}
+
+// ============================================================================
+// LayerBuffer::SurfaceLayerBuffer
+// ============================================================================
+
+LayerBuffer::SurfaceLayerBuffer::SurfaceLayerBuffer(
+        const sp<SurfaceFlinger>& flinger, const sp<LayerBuffer>& owner)
+    : LayerBaseClient::Surface(flinger, owner->getIdentity(), owner)
+{
+}
+
+LayerBuffer::SurfaceLayerBuffer::~SurfaceLayerBuffer()
+{
+    unregisterBuffers();
+}
+
+status_t LayerBuffer::SurfaceLayerBuffer::registerBuffers(
+        const ISurface::BufferHeap& buffers)
+{
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
+        return owner->registerBuffers(buffers);
+    return NO_INIT;
+}
+
+void LayerBuffer::SurfaceLayerBuffer::postBuffer(ssize_t offset)
+{
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
+        owner->postBuffer(offset);
+}
+
+void LayerBuffer::SurfaceLayerBuffer::unregisterBuffers()
+{
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
+        owner->unregisterBuffers();
+}
+
+sp<OverlayRef> LayerBuffer::SurfaceLayerBuffer::createOverlay(
+        uint32_t w, uint32_t h, int32_t format, int32_t orientation) {
+    sp<OverlayRef> result;
+    sp<LayerBuffer> owner(getOwner());
+    if (owner != 0)
+        result = owner->createOverlay(w, h, format, orientation);
+    return result;
+}
+
+// ============================================================================
+// LayerBuffer::Buffer
+// ============================================================================
+
+LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers,
+        ssize_t offset, size_t bufferSize)
+    : mBufferHeap(buffers), mSupportsCopybit(false)
+{
+    NativeBuffer& src(mNativeBuffer);
+    src.crop.l = 0;
+    src.crop.t = 0;
+    src.crop.r = buffers.w;
+    src.crop.b = buffers.h;
+
+    src.img.w       = buffers.hor_stride ?: buffers.w;
+    src.img.h       = buffers.ver_stride ?: buffers.h;
+    src.img.format  = buffers.format;
+    src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);
+    src.img.handle  = 0;
+
+    gralloc_module_t const * module = LayerBuffer::getGrallocModule();
+    if (module && module->perform) {
+        int err = module->perform(module,
+                GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,
+                buffers.heap->heapID(), bufferSize,
+                offset, buffers.heap->base(),
+                &src.img.handle);
+
+        // we can fail here is the passed buffer is purely software
+        mSupportsCopybit = (err == NO_ERROR);
+    }
+ }
+
+LayerBuffer::Buffer::~Buffer()
+{
+    NativeBuffer& src(mNativeBuffer);
+    if (src.img.handle) {
+        native_handle_delete(src.img.handle);
+    }
+}
+
+// ============================================================================
+// LayerBuffer::Source
+// LayerBuffer::BufferSource
+// LayerBuffer::OverlaySource
+// ============================================================================
+
+LayerBuffer::Source::Source(LayerBuffer& layer)
+    : mLayer(layer)
+{    
+}
+LayerBuffer::Source::~Source() {    
+}
+void LayerBuffer::Source::onDraw(const Region& clip) const {
+}
+void LayerBuffer::Source::onTransaction(uint32_t flags) {
+}
+void LayerBuffer::Source::onVisibilityResolved(
+        const Transform& planeTransform) {
+}
+void LayerBuffer::Source::postBuffer(ssize_t offset) {
+}
+void LayerBuffer::Source::unregisterBuffers() {
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::BufferSource::BufferSource(LayerBuffer& layer,
+        const ISurface::BufferHeap& buffers)
+    : Source(layer), mStatus(NO_ERROR), mBufferSize(0)
+{
+    if (buffers.heap == NULL) {
+        // this is allowed, but in this case, it is illegal to receive
+        // postBuffer(). The surface just erases the framebuffer with
+        // fully transparent pixels.
+        mBufferHeap = buffers;
+        mLayer.setNeedsBlending(false);
+        return;
+    }
+
+    status_t err = (buffers.heap->heapID() >= 0) ? NO_ERROR : NO_INIT;
+    if (err != NO_ERROR) {
+        LOGE("LayerBuffer::BufferSource: invalid heap (%s)", strerror(err));
+        mStatus = err;
+        return;
+    }
+    
+    PixelFormatInfo info;
+    err = getPixelFormatInfo(buffers.format, &info);
+    if (err != NO_ERROR) {
+        LOGE("LayerBuffer::BufferSource: invalid format %d (%s)",
+                buffers.format, strerror(err));
+        mStatus = err;
+        return;
+    }
+
+    if (buffers.hor_stride<0 || buffers.ver_stride<0) {
+        LOGE("LayerBuffer::BufferSource: invalid parameters "
+             "(w=%d, h=%d, xs=%d, ys=%d)", 
+             buffers.w, buffers.h, buffers.hor_stride, buffers.ver_stride);
+        mStatus = BAD_VALUE;
+        return;
+    }
+
+    mBufferHeap = buffers;
+    mLayer.setNeedsBlending((info.h_alpha - info.l_alpha) > 0);    
+    mBufferSize = info.getScanlineSize(buffers.hor_stride)*buffers.ver_stride;
+    mLayer.forceVisibilityTransaction();
+}
+
+LayerBuffer::BufferSource::~BufferSource()
+{    
+    class MessageDestroyTexture : public MessageBase {
+        SurfaceFlinger* flinger;
+        GLuint name;
+    public:
+        MessageDestroyTexture(
+                SurfaceFlinger* flinger, GLuint name)
+            : flinger(flinger), name(name) { }
+        virtual bool handler() {
+            glDeleteTextures(1, &name);
+            return true;
+        }
+    };
+
+    if (mTexture.name != -1U) {
+        // GL textures can only be destroyed from the GL thread
+        getFlinger()->mEventQueue.postMessage(
+                new MessageDestroyTexture(getFlinger(), mTexture.name) );
+    }
+    if (mTexture.image != EGL_NO_IMAGE_KHR) {
+        EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
+        eglDestroyImageKHR(dpy, mTexture.image);
+    }
+}
+
+void LayerBuffer::BufferSource::postBuffer(ssize_t offset)
+{    
+    ISurface::BufferHeap buffers;
+    { // scope for the lock
+        Mutex::Autolock _l(mBufferSourceLock);
+        buffers = mBufferHeap;
+        if (buffers.heap != 0) {
+            const size_t memorySize = buffers.heap->getSize();
+            if ((size_t(offset) + mBufferSize) > memorySize) {
+                LOGE("LayerBuffer::BufferSource::postBuffer() "
+                     "invalid buffer (offset=%d, size=%d, heap-size=%d",
+                     int(offset), int(mBufferSize), int(memorySize));
+                return;
+            }
+        }
+    }
+
+    sp<Buffer> buffer;
+    if (buffers.heap != 0) {
+        buffer = new LayerBuffer::Buffer(buffers, offset, mBufferSize);
+        if (buffer->getStatus() != NO_ERROR)
+            buffer.clear();
+        setBuffer(buffer);
+        mLayer.invalidate();
+    }
+}
+
+void LayerBuffer::BufferSource::unregisterBuffers()
+{
+    Mutex::Autolock _l(mBufferSourceLock);
+    mBufferHeap.heap.clear();
+    mBuffer.clear();
+    mLayer.invalidate();
+}
+
+sp<LayerBuffer::Buffer> LayerBuffer::BufferSource::getBuffer() const
+{
+    Mutex::Autolock _l(mBufferSourceLock);
+    return mBuffer;
+}
+
+void LayerBuffer::BufferSource::setBuffer(const sp<LayerBuffer::Buffer>& buffer)
+{
+    Mutex::Autolock _l(mBufferSourceLock);
+    mBuffer = buffer;
+}
+
+void LayerBuffer::BufferSource::onDraw(const Region& clip) const 
+{
+    sp<Buffer> ourBuffer(getBuffer());
+    if (UNLIKELY(ourBuffer == 0))  {
+        // nothing to do, we don't have a buffer
+        mLayer.clearWithOpenGL(clip);
+        return;
+    }
+
+    status_t err = NO_ERROR;
+    NativeBuffer src(ourBuffer->getBuffer());
+    const Rect transformedBounds(mLayer.getTransformedBounds());
+
+#if defined(EGL_ANDROID_image_native_buffer)
+    if (GLExtensions::getInstance().haveDirectTexture()) {
+        err = INVALID_OPERATION;
+        if (ourBuffer->supportsCopybit()) {
+            copybit_device_t* copybit = mLayer.mBlitEngine;
+            if (copybit && err != NO_ERROR) {
+                // create our EGLImageKHR the first time
+                err = initTempBuffer();
+                if (err == NO_ERROR) {
+                    // NOTE: Assume the buffer is allocated with the proper USAGE flags
+                    const NativeBuffer& dst(mTempBuffer);
+                    region_iterator clip(Region(Rect(dst.crop.r, dst.crop.b)));
+                    copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
+                    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 0xFF);
+                    copybit->set_parameter(copybit, COPYBIT_DITHER, COPYBIT_ENABLE);
+                    err = copybit->stretch(copybit, &dst.img, &src.img,
+                            &dst.crop, &src.crop, &clip);
+                    if (err != NO_ERROR) {
+                        clearTempBufferImage();
+                    }
+                }
+            }
+        }
+    }
+#endif
+    else {
+        err = INVALID_OPERATION;
+    }
+
+    if (err != NO_ERROR) {
+        // slower fallback
+        GGLSurface t;
+        t.version = sizeof(GGLSurface);
+        t.width  = src.crop.r;
+        t.height = src.crop.b;
+        t.stride = src.img.w;
+        t.vstride= src.img.h;
+        t.format = src.img.format;
+        t.data = (GGLubyte*)src.img.base;
+        const Region dirty(Rect(t.width, t.height));
+        mTextureManager.loadTexture(&mTexture, dirty, t);
+    }
+
+    mLayer.setBufferTransform(mBufferHeap.transform);
+    mLayer.drawWithOpenGL(clip, mTexture);
+}
+
+status_t LayerBuffer::BufferSource::initTempBuffer() const
+{
+    // figure out the size we need now
+    const ISurface::BufferHeap& buffers(mBufferHeap);
+    uint32_t w = mLayer.mTransformedBounds.width();
+    uint32_t h = mLayer.mTransformedBounds.height();
+    if (buffers.w * h != buffers.h * w) {
+        int t = w; w = h; h = t;
+    }
+
+    // we're in the copybit case, so make sure we can handle this blit
+    // we don't have to keep the aspect ratio here
+    copybit_device_t* copybit = mLayer.mBlitEngine;
+    const int down = copybit->get(copybit, COPYBIT_MINIFICATION_LIMIT);
+    const int up = copybit->get(copybit, COPYBIT_MAGNIFICATION_LIMIT);
+    if (buffers.w > w*down)     w = buffers.w / down;
+    else if (w > buffers.w*up)  w = buffers.w*up;
+    if (buffers.h > h*down)     h = buffers.h / down;
+    else if (h > buffers.h*up)  h = buffers.h*up;
+
+    if (mTexture.image != EGL_NO_IMAGE_KHR) {
+        // we have an EGLImage, make sure the needed size didn't change
+        if (w!=mTexture.width || h!= mTexture.height) {
+            // delete the EGLImage and texture
+            clearTempBufferImage();
+        } else {
+            // we're good, we have an EGLImageKHR and it's (still) the
+            // right size
+            return NO_ERROR;
+        }
+    }
+
+    // figure out if we need linear filtering
+    if (buffers.w * h == buffers.h * w) {
+        // same pixel area, don't use filtering
+        mLayer.mNeedsFiltering = false;
+    }
+
+    // Allocate a temporary buffer and create the corresponding EGLImageKHR
+    // once the EGLImage has been created we don't need the
+    // graphic buffer reference anymore.
+    sp<GraphicBuffer> buffer = new GraphicBuffer(
+            w, h, HAL_PIXEL_FORMAT_RGB_565,
+            GraphicBuffer::USAGE_HW_TEXTURE |
+            GraphicBuffer::USAGE_HW_2D);
+
+    status_t err = buffer->initCheck();
+    if (err == NO_ERROR) {
+        NativeBuffer& dst(mTempBuffer);
+        dst.img.w = buffer->getStride();
+        dst.img.h = h;
+        dst.img.format = buffer->getPixelFormat();
+        dst.img.handle = (native_handle_t *)buffer->handle;
+        dst.img.base = 0;
+        dst.crop.l = 0;
+        dst.crop.t = 0;
+        dst.crop.r = w;
+        dst.crop.b = h;
+
+        EGLDisplay dpy(getFlinger()->graphicPlane(0).getEGLDisplay());
+        err = mTextureManager.initEglImage(&mTexture, dpy, buffer);
+    }
+
+    return err;
+}
+
+void LayerBuffer::BufferSource::clearTempBufferImage() const
+{
+    // delete the image
+    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;
+}
+
+// ---------------------------------------------------------------------------
+
+LayerBuffer::OverlaySource::OverlaySource(LayerBuffer& layer,
+        sp<OverlayRef>* overlayRef, 
+        uint32_t w, uint32_t h, int32_t format, int32_t orientation)
+    : Source(layer), mVisibilityChanged(false),
+    mOverlay(0), mOverlayHandle(0), mOverlayDevice(0), mOrientation(orientation)
+{
+    overlay_control_device_t* overlay_dev = getFlinger()->getOverlayEngine();
+    if (overlay_dev == NULL) {
+        // overlays not supported
+        return;
+    }
+
+    mOverlayDevice = overlay_dev;
+    overlay_t* overlay = overlay_dev->createOverlay(overlay_dev, w, h, format);
+    if (overlay == NULL) {
+        // couldn't create the overlay (no memory? no more overlays?)
+        return;
+    }
+
+    // enable dithering...
+    overlay_dev->setParameter(overlay_dev, overlay, 
+            OVERLAY_DITHER, OVERLAY_ENABLE);
+
+    mOverlay = overlay;
+    mWidth = overlay->w;
+    mHeight = overlay->h;
+    mFormat = overlay->format; 
+    mWidthStride = overlay->w_stride;
+    mHeightStride = overlay->h_stride;
+    mInitialized = false;
+
+    mOverlayHandle = overlay->getHandleRef(overlay);
+    
+    sp<OverlayChannel> channel = new OverlayChannel( &layer );
+
+    *overlayRef = new OverlayRef(mOverlayHandle, channel,
+            mWidth, mHeight, mFormat, mWidthStride, mHeightStride);
+    getFlinger()->signalEvent();
+}
+
+LayerBuffer::OverlaySource::~OverlaySource()
+{
+    if (mOverlay && mOverlayDevice) {
+        overlay_control_device_t* overlay_dev = mOverlayDevice;
+        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
+    }
+}
+
+void LayerBuffer::OverlaySource::onDraw(const Region& clip) const
+{
+    // this would be where the color-key would be set, should we need it.
+    GLclampf red = 0;
+    GLclampf green = 0;
+    GLclampf blue = 0;
+    mLayer.clearWithOpenGL(clip, red, green, blue, 0);
+}
+
+void LayerBuffer::OverlaySource::onTransaction(uint32_t flags)
+{
+    const Layer::State& front(mLayer.drawingState());
+    const Layer::State& temp(mLayer.currentState());
+    if (temp.sequence != front.sequence) {
+        mVisibilityChanged = true;
+    }
+}
+
+void LayerBuffer::OverlaySource::onvalidateVisibility(const Transform&)
+{
+    mVisibilityChanged = true;
+}
+
+void LayerBuffer::OverlaySource::onVisibilityResolved(
+        const Transform& planeTransform)
+{
+    // this code-path must be as tight as possible, it's called each time
+    // the screen is composited.
+    if (UNLIKELY(mOverlay != 0)) {
+        if (mVisibilityChanged || !mInitialized) {
+            mVisibilityChanged = false;
+            mInitialized = true;
+            const Rect bounds(mLayer.getTransformedBounds());
+            int x = bounds.left;
+            int y = bounds.top;
+            int w = bounds.width();
+            int h = bounds.height();
+            
+            // we need a lock here to protect "destroy"
+            Mutex::Autolock _l(mOverlaySourceLock);
+            if (mOverlay) {
+                overlay_control_device_t* overlay_dev = mOverlayDevice;
+                overlay_dev->setPosition(overlay_dev, mOverlay, x,y,w,h);
+                // we need to combine the layer orientation and the
+                // user-requested orientation.
+                Transform finalTransform(Transform(mLayer.getOrientation()) *
+                        Transform(mOrientation));
+                overlay_dev->setParameter(overlay_dev, mOverlay,
+                        OVERLAY_TRANSFORM, finalTransform.getOrientation());
+                overlay_dev->commit(overlay_dev, mOverlay);
+            }
+        }
+    }
+}
+
+void LayerBuffer::OverlaySource::destroy()
+{
+    // we need a lock here to protect "onVisibilityResolved"
+    Mutex::Autolock _l(mOverlaySourceLock);
+    if (mOverlay && mOverlayDevice) {
+        overlay_control_device_t* overlay_dev = mOverlayDevice;
+        overlay_dev->destroyOverlay(overlay_dev, mOverlay);
+        mOverlay = 0;
+    }
+}
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/LayerBuffer.h b/services/surfaceflinger/LayerBuffer.h
new file mode 100644
index 0000000..a89d8fe
--- /dev/null
+++ b/services/surfaceflinger/LayerBuffer.h
@@ -0,0 +1,224 @@
+/*
+ * 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_LAYER_BUFFER_H
+#define ANDROID_LAYER_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "LayerBase.h"
+#include "TextureManager.h"
+
+struct copybit_device_t;
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Buffer;
+class Region;
+class OverlayRef;
+
+// ---------------------------------------------------------------------------
+
+class LayerBuffer : public LayerBaseClient
+{
+    class Source : public LightRefBase<Source> {
+    public:
+        Source(LayerBuffer& layer);
+        virtual ~Source();
+        virtual void onDraw(const Region& clip) const;
+        virtual void onTransaction(uint32_t flags);
+        virtual void onVisibilityResolved(const Transform& planeTransform);
+        virtual void onvalidateVisibility(const Transform& globalTransform) { }
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual void destroy() { }
+        SurfaceFlinger* getFlinger() const { return mLayer.mFlinger.get(); }
+    protected:
+        LayerBuffer& mLayer;
+    };
+
+public:
+            LayerBuffer(SurfaceFlinger* flinger, DisplayID display,
+                    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 void drawForSreenShot() const;
+    virtual uint32_t doTransaction(uint32_t flags);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+    virtual void validateVisibility(const Transform& globalTransform);
+
+    status_t registerBuffers(const ISurface::BufferHeap& buffers);
+    void postBuffer(ssize_t offset);
+    void unregisterBuffers();
+    sp<OverlayRef> createOverlay(uint32_t w, uint32_t h, int32_t format,
+            int32_t orientation);
+    
+    sp<Source> getSource() const;
+    sp<Source> clearSource();
+    void setNeedsBlending(bool blending);
+    Rect getTransformedBounds() const {
+        return mTransformedBounds;
+    }
+
+    void serverDestroy();
+
+private:
+    struct NativeBuffer {
+        copybit_image_t   img;
+        copybit_rect_t    crop;
+    };
+
+    static gralloc_module_t const* sGrallocModule;
+    static gralloc_module_t const* getGrallocModule() {
+        return sGrallocModule;
+    }
+
+    class Buffer : public LightRefBase<Buffer> {
+    public:
+        Buffer(const ISurface::BufferHeap& buffers,
+                ssize_t offset, size_t bufferSize);
+        inline bool supportsCopybit() const {
+            return mSupportsCopybit;
+        }
+        inline status_t getStatus() const {
+            return mBufferHeap.heap!=0 ? NO_ERROR : NO_INIT;
+        }
+        inline const NativeBuffer& getBuffer() const {
+            return mNativeBuffer;
+        }
+    protected:
+        friend class LightRefBase<Buffer>;
+        Buffer& operator = (const Buffer& rhs);
+        Buffer(const Buffer& rhs);
+        ~Buffer();
+    private:
+        ISurface::BufferHeap    mBufferHeap;
+        NativeBuffer            mNativeBuffer;
+        bool                    mSupportsCopybit;
+    };
+
+    class BufferSource : public Source {
+    public:
+        BufferSource(LayerBuffer& layer, const ISurface::BufferHeap& buffers);
+        virtual ~BufferSource();
+
+        status_t getStatus() const { return mStatus; }
+        sp<Buffer> getBuffer() const;
+        void setBuffer(const sp<Buffer>& buffer);
+
+        virtual void onDraw(const Region& clip) const;
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        virtual void destroy() { }
+    private:
+        status_t initTempBuffer() const;
+        void clearTempBufferImage() const;
+        mutable Mutex                   mBufferSourceLock;
+        sp<Buffer>                      mBuffer;
+        status_t                        mStatus;
+        ISurface::BufferHeap            mBufferHeap;
+        size_t                          mBufferSize;
+        mutable Texture                 mTexture;
+        mutable NativeBuffer            mTempBuffer;
+        mutable TextureManager          mTextureManager;
+    };
+    
+    class OverlaySource : public Source {
+    public:
+        OverlaySource(LayerBuffer& layer,
+                sp<OverlayRef>* overlayRef, 
+                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
+        virtual ~OverlaySource();
+        virtual void onDraw(const Region& clip) const;
+        virtual void onTransaction(uint32_t flags);
+        virtual void onVisibilityResolved(const Transform& planeTransform);
+        virtual void onvalidateVisibility(const Transform& globalTransform);
+        virtual void destroy();
+    private:
+
+        class OverlayChannel : public BnOverlay {
+            wp<LayerBuffer> mLayer;
+            virtual void destroy() {
+                sp<LayerBuffer> layer(mLayer.promote());
+                if (layer != 0) {
+                    layer->serverDestroy();
+                }
+            }
+        public:
+            OverlayChannel(const sp<LayerBuffer>& layer)
+                : mLayer(layer) {
+            }
+        };
+        
+        friend class OverlayChannel;
+        bool mVisibilityChanged;
+
+        overlay_t* mOverlay;        
+        overlay_handle_t mOverlayHandle;
+        overlay_control_device_t* mOverlayDevice;
+        uint32_t mWidth;
+        uint32_t mHeight;
+        int32_t mFormat;
+        int32_t mWidthStride;
+        int32_t mHeightStride;
+        int32_t mOrientation;
+        mutable Mutex mOverlaySourceLock;
+        bool mInitialized;
+    };
+
+
+    class SurfaceLayerBuffer : public LayerBaseClient::Surface
+    {
+    public:
+        SurfaceLayerBuffer(const sp<SurfaceFlinger>& flinger,
+                        const sp<LayerBuffer>& owner);
+        virtual ~SurfaceLayerBuffer();
+
+        virtual status_t registerBuffers(const ISurface::BufferHeap& buffers);
+        virtual void postBuffer(ssize_t offset);
+        virtual void unregisterBuffers();
+        
+        virtual sp<OverlayRef> createOverlay(
+                uint32_t w, uint32_t h, int32_t format, int32_t orientation);
+    private:
+        sp<LayerBuffer> getOwner() const {
+            return static_cast<LayerBuffer*>(Surface::getOwner().get());
+        }
+    };
+
+    mutable Mutex   mLock;
+    sp<Source>      mSource;
+    sp<Surface>     mSurface;
+    bool            mInvalidate;
+    bool            mNeedsBlending;
+    copybit_device_t* mBlitEngine;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_BUFFER_H
diff --git a/services/surfaceflinger/LayerDim.cpp b/services/surfaceflinger/LayerDim.cpp
new file mode 100644
index 0000000..80cc52c
--- /dev/null
+++ b/services/surfaceflinger/LayerDim.cpp
@@ -0,0 +1,103 @@
+/*
+ * 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 <stdlib.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/Log.h>
+
+#include <ui/GraphicBuffer.h>
+
+#include "LayerDim.h"
+#include "SurfaceFlinger.h"
+#include "DisplayHardware/DisplayHardware.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+bool LayerDim::sUseTexture;
+GLuint LayerDim::sTexId;
+EGLImageKHR LayerDim::sImage;
+int32_t LayerDim::sWidth;
+int32_t LayerDim::sHeight;
+
+// ---------------------------------------------------------------------------
+
+LayerDim::LayerDim(SurfaceFlinger* flinger, DisplayID display,
+        const sp<Client>& client)
+    : LayerBaseClient(flinger, display, client)
+{
+}
+
+void LayerDim::initDimmer(SurfaceFlinger* flinger, uint32_t w, uint32_t h)
+{
+    sTexId = -1;
+    sImage = EGL_NO_IMAGE_KHR;
+    sWidth = w;
+    sHeight = h;
+    sUseTexture = false;
+}
+
+LayerDim::~LayerDim()
+{
+}
+
+void LayerDim::onDraw(const Region& clip) const
+{
+    const State& s(drawingState());
+    Region::const_iterator it = clip.begin();
+    Region::const_iterator const end = clip.end();
+    if (s.alpha>0 && (it != end)) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        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);
+        glColor4f(0, 0, 0, alpha);
+
+#if defined(GL_OES_EGL_image_external)
+        if (GLExtensions::getInstance().haveTextureExternal()) {
+            glDisable(GL_TEXTURE_EXTERNAL_OES);
+        }
+#endif
+        glDisable(GL_TEXTURE_2D);
+
+        GLshort w = sWidth;
+        GLshort h = sHeight;
+        const GLshort vertices[4][2] = {
+                { 0, 0 },
+                { 0, h },
+                { w, h },
+                { w, 0 }
+        };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+
+        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);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/LayerDim.h b/services/surfaceflinger/LayerDim.h
new file mode 100644
index 0000000..f032314
--- /dev/null
+++ b/services/surfaceflinger/LayerDim.h
@@ -0,0 +1,56 @@
+/*
+ * 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_LAYER_DIM_H
+#define ANDROID_LAYER_DIM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "LayerBase.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class LayerDim : public LayerBaseClient
+{
+    static bool sUseTexture;
+    static GLuint sTexId;
+    static EGLImageKHR sImage;
+    static int32_t sWidth;
+    static int32_t sHeight;
+public:    
+                LayerDim(SurfaceFlinger* flinger, DisplayID display,
+                        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);
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_LAYER_DIM_H
diff --git a/libs/surfaceflinger/MODULE_LICENSE_APACHE2 b/services/surfaceflinger/MODULE_LICENSE_APACHE2
similarity index 100%
rename from libs/surfaceflinger/MODULE_LICENSE_APACHE2
rename to services/surfaceflinger/MODULE_LICENSE_APACHE2
diff --git a/services/surfaceflinger/MessageQueue.cpp b/services/surfaceflinger/MessageQueue.cpp
new file mode 100644
index 0000000..aebe1b8
--- /dev/null
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 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 <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/Log.h>
+#include <binder/IPCThreadState.h>
+
+#include "MessageQueue.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+void MessageList::insert(const sp<MessageBase>& node) 
+{
+    LIST::iterator cur(mList.begin());
+    LIST::iterator end(mList.end());
+    while (cur != end) {
+        if (*node < **cur) {
+            mList.insert(cur, node);
+            return;
+        }
+        ++cur;
+    }
+    mList.insert(++end, node);
+}
+
+void MessageList::remove(MessageList::LIST::iterator pos) 
+{
+    mList.erase(pos);
+}
+
+// ---------------------------------------------------------------------------
+
+MessageQueue::MessageQueue()
+    : mInvalidate(false)
+{
+    mInvalidateMessage = new MessageBase(INVALIDATE);
+}
+
+MessageQueue::~MessageQueue()
+{
+}
+
+sp<MessageBase> MessageQueue::waitMessage(nsecs_t timeout)
+{
+    sp<MessageBase> result;
+
+    bool again;
+    do {
+        const nsecs_t timeoutTime = systemTime() + timeout;
+        while (true) {
+            Mutex::Autolock _l(mLock);
+            nsecs_t now = systemTime();
+            nsecs_t nextEventTime = -1;
+
+            LIST::iterator cur(mMessages.begin());
+            if (cur != mMessages.end()) {
+                result = *cur;
+            }
+            
+            if (result != 0) {
+                if (result->when <= now) {
+                    // there is a message to deliver
+                    mMessages.remove(cur);
+                    break;
+                }
+                nextEventTime = result->when;
+                result = 0;
+            }
+
+            // see if we have an invalidate message
+            if (mInvalidate) {
+                mInvalidate = false;
+                mInvalidateMessage->when = now;
+                result = mInvalidateMessage;
+                break;
+            }
+
+            if (timeout >= 0) {
+                if (timeoutTime < now) {
+                    // we timed-out, return a NULL message
+                    result = 0;
+                    break;
+                }
+                if (nextEventTime > 0) {
+                    if (nextEventTime > timeoutTime) {
+                        nextEventTime = timeoutTime;
+                    }
+                } else {
+                    nextEventTime = timeoutTime;
+                }
+            }
+
+            if (nextEventTime >= 0) {
+                //LOGD("nextEventTime = %lld ms", nextEventTime);
+                if (nextEventTime > 0) {
+                    // we're about to wait, flush the binder command buffer
+                    IPCThreadState::self()->flushCommands();
+                    const nsecs_t reltime = nextEventTime - systemTime();
+                    if (reltime > 0) {
+                        mCondition.waitRelative(mLock, reltime);
+                    }
+                }
+            } else {
+                //LOGD("going to wait");
+                // we're about to wait, flush the binder command buffer
+                IPCThreadState::self()->flushCommands();
+                mCondition.wait(mLock);
+            }
+        } 
+        // here we're not holding the lock anymore
+
+        if (result == 0)
+            break;
+
+        again = result->handler();
+        if (again) {
+            // the message has been processed. release our reference to it
+            // without holding the lock.
+            result->notify();
+            result = 0;
+        }
+        
+    } while (again);
+
+    return result;
+}
+
+status_t MessageQueue::postMessage(
+        const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
+{
+    return queueMessage(message, relTime, flags);
+}
+
+status_t MessageQueue::invalidate() {
+    Mutex::Autolock _l(mLock);
+    mInvalidate = true;
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+status_t MessageQueue::queueMessage(
+        const sp<MessageBase>& message, nsecs_t relTime, uint32_t flags)
+{
+    Mutex::Autolock _l(mLock);
+    message->when = systemTime() + relTime;
+    mMessages.insert(message);
+    
+    //LOGD("MessageQueue::queueMessage time = %lld ms", message->when);
+    //dumpLocked(message);
+
+    mCondition.signal();
+    return NO_ERROR;
+}
+
+void MessageQueue::dump(const sp<MessageBase>& message)
+{
+    Mutex::Autolock _l(mLock);
+    dumpLocked(message);
+}
+
+void MessageQueue::dumpLocked(const sp<MessageBase>& message)
+{
+    LIST::const_iterator cur(mMessages.begin());
+    LIST::const_iterator end(mMessages.end());
+    int c = 0;
+    while (cur != end) {
+        const char tick = (*cur == message) ? '>' : ' ';
+        LOGD("%c %d: msg{.what=%08x, when=%lld}",
+                tick, c, (*cur)->what, (*cur)->when);
+        ++cur;
+        c++;
+    }
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/MessageQueue.h b/services/surfaceflinger/MessageQueue.h
new file mode 100644
index 0000000..890f809
--- /dev/null
+++ b/services/surfaceflinger/MessageQueue.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 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_MESSAGE_QUEUE_H
+#define ANDROID_MESSAGE_QUEUE_H
+
+#include <stdint.h>
+#include <errno.h>
+#include <sys/types.h>
+
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/List.h>
+
+#include "Barrier.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MessageBase;
+
+class MessageList 
+{
+    List< sp<MessageBase> > mList;
+    typedef List< sp<MessageBase> > LIST;
+public:
+    inline LIST::iterator begin()                { return mList.begin(); }
+    inline LIST::const_iterator begin() const    { return mList.begin(); }
+    inline LIST::iterator end()                  { return mList.end(); }
+    inline LIST::const_iterator end() const      { return mList.end(); }
+    inline bool isEmpty() const { return mList.empty(); }
+    void insert(const sp<MessageBase>& node);
+    void remove(LIST::iterator pos);
+};
+
+// ============================================================================
+
+class MessageBase : 
+    public LightRefBase<MessageBase>
+{
+public:
+    nsecs_t     when;
+    uint32_t    what;
+    int32_t     arg0;    
+
+    MessageBase() : when(0), what(0), arg0(0) { }
+    MessageBase(uint32_t what, int32_t arg0=0)
+        : when(0), what(what), arg0(arg0) { }
+    
+    // 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>;
+};
+
+inline bool operator < (const MessageBase& lhs, const MessageBase& rhs) {
+    return lhs.when < rhs.when;
+}
+
+// ---------------------------------------------------------------------------
+
+class MessageQueue
+{
+    typedef List< sp<MessageBase> > LIST;
+public:
+
+    MessageQueue();
+    ~MessageQueue();
+
+    // pre-defined messages
+    enum {
+        INVALIDATE = '_upd'
+    };
+
+    sp<MessageBase> waitMessage(nsecs_t timeout = -1);
+    
+    status_t postMessage(const sp<MessageBase>& message,
+            nsecs_t reltime=0, uint32_t flags = 0);
+
+    status_t invalidate();
+    
+    void dump(const sp<MessageBase>& message);
+
+private:
+    status_t queueMessage(const sp<MessageBase>& message,
+            nsecs_t reltime, uint32_t flags);
+    void dumpLocked(const sp<MessageBase>& message);
+    
+    Mutex           mLock;
+    Condition       mCondition;
+    MessageList     mMessages;
+    bool            mInvalidate;
+    sp<MessageBase> mInvalidateMessage;
+};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif /* ANDROID_MESSAGE_QUEUE_H */
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
new file mode 100644
index 0000000..a9b3965
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -0,0 +1,2479 @@
+/*
+ * 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 <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <math.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <cutils/log.h>
+#include <cutils/properties.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/MemoryHeapBase.h>
+
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <utils/StopWatch.h>
+
+#include <ui/GraphicBufferAllocator.h>
+#include <ui/GraphicLog.h>
+#include <ui/PixelFormat.h>
+
+#include <pixelflinger/pixelflinger.h>
+#include <GLES/gl.h>
+
+#include "clz.h"
+#include "GLExtensions.h"
+#include "Layer.h"
+#include "LayerBlur.h"
+#include "LayerBuffer.h"
+#include "LayerDim.h"
+#include "SurfaceFlinger.h"
+
+#include "DisplayHardware/DisplayHardware.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 DISPLAY_COUNT       1
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+SurfaceFlinger::SurfaceFlinger()
+    :   BnSurfaceComposer(), Thread(false),
+        mTransactionFlags(0),
+        mTransactionCount(0),
+        mResizeTransationPending(false),
+        mLayersRemoved(false),
+        mBootTime(systemTime()),
+        mHardwareTest("android.permission.HARDWARE_TEST"),
+        mAccessSurfaceFlinger("android.permission.ACCESS_SURFACE_FLINGER"),
+        mReadFramebuffer("android.permission.READ_FRAME_BUFFER"),
+        mDump("android.permission.DUMP"),
+        mVisibleRegionsDirty(false),
+        mDeferReleaseConsole(false),
+        mFreezeDisplay(false),
+        mElectronBeamAnimationMode(0),
+        mFreezeCount(0),
+        mFreezeDisplayTime(0),
+        mDebugRegion(0),
+        mDebugBackground(0),
+        mDebugInSwapBuffers(0),
+        mLastSwapBufferTime(0),
+        mDebugInTransaction(0),
+        mLastTransactionTime(0),
+        mBootFinished(false),
+        mConsoleSignals(0),
+        mSecureFrameBuffer(0)
+{
+    init();
+}
+
+void SurfaceFlinger::init()
+{
+    LOGI("SurfaceFlinger is starting");
+
+    // debugging stuff...
+    char value[PROPERTY_VALUE_MAX];
+    property_get("debug.sf.showupdates", value, "0");
+    mDebugRegion = atoi(value);
+    property_get("debug.sf.showbackground", value, "0");
+    mDebugBackground = atoi(value);
+
+    LOGI_IF(mDebugRegion,       "showupdates enabled");
+    LOGI_IF(mDebugBackground,   "showbackground enabled");
+}
+
+SurfaceFlinger::~SurfaceFlinger()
+{
+    glDeleteTextures(1, &mWormholeTexName);
+}
+
+overlay_control_device_t* SurfaceFlinger::getOverlayEngine() const
+{
+    return graphicPlane(0).displayHardware().getOverlayEngine();
+}
+
+sp<IMemoryHeap> SurfaceFlinger::getCblk() const
+{
+    return mServerHeap;
+}
+
+sp<ISurfaceComposerClient> SurfaceFlinger::createConnection()
+{
+    sp<ISurfaceComposerClient> bclient;
+    sp<Client> client(new Client(this));
+    status_t err = client->initCheck();
+    if (err == NO_ERROR) {
+        bclient = client;
+    }
+    return bclient;
+}
+
+sp<ISurfaceComposerClient> SurfaceFlinger::createClientConnection()
+{
+    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);
+    const GraphicPlane& plane(mGraphicPlanes[dpy]);
+    return plane;
+}
+
+GraphicPlane& SurfaceFlinger::graphicPlane(int dpy)
+{
+    return const_cast<GraphicPlane&>(
+        const_cast<SurfaceFlinger const *>(this)->graphicPlane(dpy));
+}
+
+void SurfaceFlinger::bootFinished()
+{
+    const nsecs_t now = systemTime();
+    const nsecs_t duration = now - mBootTime;
+    LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );  
+    mBootFinished = true;
+    property_set("ctl.stop", "bootanim");
+}
+
+void SurfaceFlinger::onFirstRef()
+{
+    run("SurfaceFlinger", PRIORITY_URGENT_DISPLAY);
+
+    // Wait for the main thread to be done with its initialization
+    mReadyToRunBarrier.wait();
+}
+
+static inline uint16_t pack565(int r, int g, int b) {
+    return (r<<11)|(g<<5)|b;
+}
+
+status_t SurfaceFlinger::readyToRun()
+{
+    LOGI(   "SurfaceFlinger's main thread ready to run. "
+            "Initializing graphics H/W...");
+
+    // we only support one display currently
+    int dpy = 0;
+
+    {
+        // initialize the main display
+        GraphicPlane& plane(graphicPlane(dpy));
+        DisplayHardware* const hw = new DisplayHardware(this, dpy);
+        plane.setDisplayHardware(hw);
+    }
+
+    // create the shared control-block
+    mServerHeap = new MemoryHeapBase(4096,
+            MemoryHeapBase::READ_ONLY, "SurfaceFlinger read-only heap");
+    LOGE_IF(mServerHeap==0, "can't create shared memory dealer");
+    
+    mServerCblk = static_cast<surface_flinger_cblk_t*>(mServerHeap->getBase());
+    LOGE_IF(mServerCblk==0, "can't get to shared control block's address");
+    
+    new(mServerCblk) surface_flinger_cblk_t;
+
+    // initialize primary screen
+    // (other display should be initialized in the same manner, but
+    // asynchronously, as they could come and go. None of this is supported
+    // yet).
+    const GraphicPlane& plane(graphicPlane(dpy));
+    const DisplayHardware& hw = plane.displayHardware();
+    const uint32_t w = hw.getWidth();
+    const uint32_t h = hw.getHeight();
+    const uint32_t f = hw.getFormat();
+    hw.makeCurrent();
+
+    // initialize the shared control block
+    mServerCblk->connected |= 1<<dpy;
+    display_cblk_t* dcblk = mServerCblk->displays + dpy;
+    memset(dcblk, 0, sizeof(display_cblk_t));
+    dcblk->w            = plane.getWidth();
+    dcblk->h            = plane.getHeight();
+    dcblk->format       = f;
+    dcblk->orientation  = ISurfaceComposer::eOrientationDefault;
+    dcblk->xdpi         = hw.getDpiX();
+    dcblk->ydpi         = hw.getDpiY();
+    dcblk->fps          = hw.getRefreshRate();
+    dcblk->density      = hw.getDensity();
+
+    // Initialize OpenGL|ES
+    glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
+    glPixelStorei(GL_PACK_ALIGNMENT, 4); 
+    glEnableClientState(GL_VERTEX_ARRAY);
+    glEnable(GL_SCISSOR_TEST);
+    glShadeModel(GL_FLAT);
+    glDisable(GL_DITHER);
+    glDisable(GL_CULL_FACE);
+
+    const uint16_t g0 = pack565(0x0F,0x1F,0x0F);
+    const uint16_t g1 = pack565(0x17,0x2f,0x17);
+    const uint16_t textureData[4] = { g0, g1, g1, g0 };
+    glGenTextures(1, &mWormholeTexName);
+    glBindTexture(GL_TEXTURE_2D, mWormholeTexName);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 2, 2, 0,
+            GL_RGB, GL_UNSIGNED_SHORT_5_6_5, textureData);
+
+    glViewport(0, 0, w, h);
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    glOrthof(0, w, h, 0, 0, 1);
+
+   LayerDim::initDimmer(this, w, h);
+
+    mReadyToRunBarrier.open();
+
+    /*
+     *  We're now ready to accept clients...
+     */
+
+    // start boot animation
+    property_set("ctl.start", "bootanim");
+    
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Events Handler
+#endif
+
+void SurfaceFlinger::waitForEvent()
+{
+    while (true) {
+        nsecs_t timeout = -1;
+        const nsecs_t freezeDisplayTimeout = ms2ns(5000);
+        if (UNLIKELY(isFrozen())) {
+            // wait 5 seconds
+            const nsecs_t now = systemTime();
+            if (mFreezeDisplayTime == 0) {
+                mFreezeDisplayTime = now;
+            }
+            nsecs_t waitTime = freezeDisplayTimeout - (now - mFreezeDisplayTime);
+            timeout = waitTime>0 ? waitTime : 0;
+        }
+
+        sp<MessageBase> msg = mEventQueue.waitMessage(timeout);
+
+        // see if we timed out
+        if (isFrozen()) {
+            const nsecs_t now = systemTime();
+            nsecs_t frozenTime = (now - mFreezeDisplayTime);
+            if (frozenTime >= freezeDisplayTimeout) {
+                // we timed out and are still frozen
+                LOGW("timeout expired mFreezeDisplay=%d, mFreezeCount=%d",
+                        mFreezeDisplay, mFreezeCount);
+                mFreezeDisplayTime = 0;
+                mFreezeCount = 0;
+                mFreezeDisplay = false;
+            }
+        }
+
+        if (msg != 0) {
+            switch (msg->what) {
+                case MessageQueue::INVALIDATE:
+                    // invalidate message, just return to the main loop
+                    return;
+            }
+        }
+    }
+}
+
+void SurfaceFlinger::signalEvent() {
+    mEventQueue.invalidate();
+}
+
+void SurfaceFlinger::signal() const {
+    // this is the IPC call
+    const_cast<SurfaceFlinger*>(this)->signalEvent();
+}
+
+status_t SurfaceFlinger::postMessageAsync(const sp<MessageBase>& msg,
+        nsecs_t reltime, uint32_t flags)
+{
+    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;
+}
+
+// ----------------------------------------------------------------------------
+#if 0
+#pragma mark -
+#pragma mark Main loop
+#endif
+
+bool SurfaceFlinger::threadLoop()
+{
+    waitForEvent();
+
+    // check for transactions
+    if (UNLIKELY(mConsoleSignals)) {
+        handleConsoleEvents();
+    }
+
+    if (LIKELY(mTransactionCount == 0)) {
+        // if we're in a global transaction, don't do anything.
+        const uint32_t mask = eTransactionNeeded | eTraversalNeeded;
+        uint32_t transactionFlags = getTransactionFlags(mask);
+        if (LIKELY(transactionFlags)) {
+            handleTransaction(transactionFlags);
+        }
+    }
+
+    // post surfaces (if needed)
+    handlePageFlip();
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    if (LIKELY(hw.canDraw() && !isFrozen())) {
+        // repaint the framebuffer (if needed)
+
+        const int index = hw.getCurrentBufferIndex();
+        GraphicLog& logger(GraphicLog::getInstance());
+
+        logger.log(GraphicLog::SF_REPAINT, index);
+        handleRepaint();
+
+        // inform the h/w that we're done compositing
+        logger.log(GraphicLog::SF_COMPOSITION_COMPLETE, index);
+        hw.compositionComplete();
+
+        // release the clients before we flip ('cause flip might block)
+        logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
+        unlockClients();
+
+        logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
+        postFramebuffer();
+
+        logger.log(GraphicLog::SF_REPAINT_DONE, index);
+    } else {
+        // pretend we did the post
+        unlockClients();
+        usleep(16667); // 60 fps period
+    }
+    return true;
+}
+
+void SurfaceFlinger::postFramebuffer()
+{
+    if (!mInvalidRegion.isEmpty()) {
+        const DisplayHardware& hw(graphicPlane(0).displayHardware());
+        const nsecs_t now = systemTime();
+        mDebugInSwapBuffers = now;
+        hw.flip(mInvalidRegion);
+        mLastSwapBufferTime = systemTime() - now;
+        mDebugInSwapBuffers = 0;
+        mInvalidRegion.clear();
+    }
+}
+
+void SurfaceFlinger::handleConsoleEvents()
+{
+    // something to do with the console
+    const DisplayHardware& hw = graphicPlane(0).displayHardware();
+
+    int what = android_atomic_and(0, &mConsoleSignals);
+    if (what & eConsoleAcquired) {
+        hw.acquireScreen();
+        // this is a temporary work-around, eventually this should be called
+        // by the power-manager
+        SurfaceFlinger::turnElectronBeamOn(mElectronBeamAnimationMode);
+    }
+
+    if (mDeferReleaseConsole && hw.isScreenAcquired()) {
+        // We got the release signal before the acquire signal
+        mDeferReleaseConsole = false;
+        hw.releaseScreen();
+    }
+
+    if (what & eConsoleReleased) {
+        if (hw.isScreenAcquired()) {
+            hw.releaseScreen();
+        } else {
+            mDeferReleaseConsole = true;
+        }
+    }
+
+    mDirtyRegion.set(hw.bounds());
+}
+
+void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
+{
+    Vector< sp<LayerBase> > ditchedLayers;
+
+    /*
+     * Perform and commit the transaction
+     */
+
+    { // scope for the lock
+        Mutex::Autolock _l(mStateLock);
+        const nsecs_t now = systemTime();
+        mDebugInTransaction = now;
+        handleTransactionLocked(transactionFlags, ditchedLayers);
+        mLastTransactionTime = systemTime() - now;
+        mDebugInTransaction = 0;
+        // here the transaction has been committed
+    }
+
+    /*
+     * 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) {
+            //LOGD("ditching layer %p", ditchedLayers[i].get());
+            ditchedLayers[i]->ditch();
+        }
+    }
+}
+
+void SurfaceFlinger::handleTransactionLocked(
+        uint32_t transactionFlags, Vector< sp<LayerBase> >& ditchedLayers)
+{
+    const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
+    const size_t count = currentLayers.size();
+
+    /*
+     * Traversal of the children
+     * (perform the transaction for each of them if needed)
+     */
+
+    const bool layersNeedTransaction = transactionFlags & eTraversalNeeded;
+    if (layersNeedTransaction) {
+        for (size_t i=0 ; i<count ; i++) {
+            const sp<LayerBase>& layer = currentLayers[i];
+            uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
+            if (!trFlags) continue;
+
+            const uint32_t flags = layer->doTransaction(0);
+            if (flags & Layer::eVisibleRegion)
+                mVisibleRegionsDirty = true;
+        }
+    }
+
+    /*
+     * Perform our own transaction if needed
+     */
+
+    if (transactionFlags & eTransactionNeeded) {
+        if (mCurrentState.orientation != mDrawingState.orientation) {
+            // the orientation has changed, recompute all visible regions
+            // and invalidate everything.
+
+            const int dpy = 0;
+            const int orientation = mCurrentState.orientation;
+            const uint32_t type = mCurrentState.orientationType;
+            GraphicPlane& plane(graphicPlane(dpy));
+            plane.setOrientation(orientation);
+
+            // update the shared control block
+            const DisplayHardware& hw(plane.displayHardware());
+            volatile display_cblk_t* dcblk = mServerCblk->displays + dpy;
+            dcblk->orientation = orientation;
+            dcblk->w = plane.getWidth();
+            dcblk->h = plane.getHeight();
+
+            mVisibleRegionsDirty = true;
+            mDirtyRegion.set(hw.bounds());
+        }
+
+        if (mCurrentState.freezeDisplay != mDrawingState.freezeDisplay) {
+            // freezing or unfreezing the display -> trigger animation if needed
+            mFreezeDisplay = mCurrentState.freezeDisplay;
+            if (mFreezeDisplay)
+                 mFreezeDisplayTime = 0;
+        }
+
+        if (currentLayers.size() > mDrawingState.layersSortedByZ.size()) {
+            // layers have been added
+            mVisibleRegionsDirty = true;
+        }
+
+        // some layers might have been removed, so
+        // we need to update the regions they're exposing.
+        if (mLayersRemoved) {
+            mLayersRemoved = false;
+            mVisibleRegionsDirty = true;
+            const LayerVector& previousLayers(mDrawingState.layersSortedByZ);
+            const size_t count = previousLayers.size();
+            for (size_t i=0 ; i<count ; i++) {
+                const sp<LayerBase>& layer(previousLayers[i]);
+                if (currentLayers.indexOf( layer ) < 0) {
+                    // this layer is not visible anymore
+                    ditchedLayers.add(layer);
+                    mDirtyRegionRemovedLayer.orSelf(layer->visibleRegionScreen);
+                }
+            }
+        }
+    }
+
+    commitTransaction();
+}
+
+sp<FreezeLock> SurfaceFlinger::getFreezeLock() const
+{
+    return new FreezeLock(const_cast<SurfaceFlinger *>(this));
+}
+
+void SurfaceFlinger::computeVisibleRegions(
+    LayerVector& currentLayers, Region& dirtyRegion, Region& opaqueRegion)
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const Transform& planeTransform(plane.transform());
+    const DisplayHardware& hw(plane.displayHardware());
+    const Region screenRegion(hw.bounds());
+
+    Region aboveOpaqueLayers;
+    Region aboveCoveredLayers;
+    Region dirty;
+
+    bool secureFrameBuffer = false;
+
+    size_t i = currentLayers.size();
+    while (i--) {
+        const sp<LayerBase>& layer = currentLayers[i];
+        layer->validateVisibility(planeTransform);
+
+        // start with the whole surface at its current location
+        const Layer::State& s(layer->drawingState());
+
+        /*
+         * opaqueRegion: area of a surface that is fully opaque.
+         */
+        Region opaqueRegion;
+
+        /*
+         * visibleRegion: area of a surface that is visible on screen
+         * and not fully transparent. This is essentially the layer's
+         * footprint minus the opaque regions above it.
+         * Areas covered by a translucent surface are considered visible.
+         */
+        Region visibleRegion;
+
+        /*
+         * coveredRegion: area of a surface that is covered by all
+         * visible regions above it (which includes the translucent areas).
+         */
+        Region coveredRegion;
+
+
+        // handle hidden surfaces by setting the visible region to empty
+        if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) {
+            const bool translucent = layer->needsBlending();
+            const Rect bounds(layer->visibleBounds());
+            visibleRegion.set(bounds);
+            visibleRegion.andSelf(screenRegion);
+            if (!visibleRegion.isEmpty()) {
+                // Remove the transparent area from the visible region
+                if (translucent) {
+                    visibleRegion.subtractSelf(layer->transparentRegionScreen);
+                }
+
+                // compute the opaque region
+                const int32_t layerOrientation = layer->getOrientation();
+                if (s.alpha==255 && !translucent &&
+                        ((layerOrientation & Transform::ROT_INVALID) == false)) {
+                    // the opaque region is the layer's footprint
+                    opaqueRegion = visibleRegion;
+                }
+            }
+        }
+
+        // Clip the covered region to the visible region
+        coveredRegion = aboveCoveredLayers.intersect(visibleRegion);
+
+        // Update aboveCoveredLayers for next (lower) layer
+        aboveCoveredLayers.orSelf(visibleRegion);
+
+        // subtract the opaque region covered by the layers above us
+        visibleRegion.subtractSelf(aboveOpaqueLayers);
+
+        // compute this layer's dirty region
+        if (layer->contentDirty) {
+            // we need to invalidate the whole region
+            dirty = visibleRegion;
+            // as well, as the old visible region
+            dirty.orSelf(layer->visibleRegionScreen);
+            layer->contentDirty = false;
+        } else {
+            /* compute the exposed region:
+             *   the exposed region consists of two components:
+             *   1) what's VISIBLE now and was COVERED before
+             *   2) what's EXPOSED now less what was EXPOSED before
+             *
+             * note that (1) is conservative, we start with the whole
+             * visible region but only keep what used to be covered by
+             * something -- which mean it may have been exposed.
+             *
+             * (2) handles areas that were not covered by anything but got
+             * exposed because of a resize.
+             */
+            const Region newExposed = visibleRegion - coveredRegion;
+            const Region oldVisibleRegion = layer->visibleRegionScreen;
+            const Region oldCoveredRegion = layer->coveredRegionScreen;
+            const Region oldExposed = oldVisibleRegion - oldCoveredRegion;
+            dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
+        }
+        dirty.subtractSelf(aboveOpaqueLayers);
+
+        // accumulate to the screen dirty region
+        dirtyRegion.orSelf(dirty);
+
+        // Update aboveOpaqueLayers for next (lower) layer
+        aboveOpaqueLayers.orSelf(opaqueRegion);
+        
+        // Store the visible region is screen space
+        layer->setVisibleRegion(visibleRegion);
+        layer->setCoveredRegion(coveredRegion);
+
+        // If a secure layer is partially visible, lock-down the screen!
+        if (layer->isSecure() && !visibleRegion.isEmpty()) {
+            secureFrameBuffer = true;
+        }
+    }
+
+    // invalidate the areas where a layer was removed
+    dirtyRegion.orSelf(mDirtyRegionRemovedLayer);
+    mDirtyRegionRemovedLayer.clear();
+
+    mSecureFrameBuffer = secureFrameBuffer;
+    opaqueRegion = aboveOpaqueLayers;
+}
+
+
+void SurfaceFlinger::commitTransaction()
+{
+    mDrawingState = mCurrentState;
+    mResizeTransationPending = false;
+    mTransactionCV.broadcast();
+}
+
+void SurfaceFlinger::handlePageFlip()
+{
+    bool visibleRegions = mVisibleRegionsDirty;
+    LayerVector& currentLayers = const_cast<LayerVector&>(
+            mDrawingState.layersSortedByZ);
+    visibleRegions |= lockPageFlip(currentLayers);
+
+        const DisplayHardware& hw = graphicPlane(0).displayHardware();
+        const Region screenRegion(hw.bounds());
+        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;
+        }
+
+    unlockPageFlip(currentLayers);
+    mDirtyRegion.andSelf(screenRegion);
+}
+
+bool SurfaceFlinger::lockPageFlip(const LayerVector& currentLayers)
+{
+    bool recomputeVisibleRegions = false;
+    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]);
+        layer->lockPageFlip(recomputeVisibleRegions);
+    }
+    return recomputeVisibleRegions;
+}
+
+void SurfaceFlinger::unlockPageFlip(const LayerVector& currentLayers)
+{
+    const GraphicPlane& plane(graphicPlane(0));
+    const Transform& planeTransform(plane.transform());
+    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]);
+        layer->unlockPageFlip(planeTransform, mDirtyRegion);
+    }
+}
+
+
+void SurfaceFlinger::handleRepaint()
+{
+    // compute the invalid region
+    mInvalidRegion.orSelf(mDirtyRegion);
+    if (mInvalidRegion.isEmpty()) {
+        // nothing to do
+        return;
+    }
+
+    if (UNLIKELY(mDebugRegion)) {
+        debugFlashRegions();
+    }
+
+    // set the frame buffer
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+
+    uint32_t flags = hw.getFlags();
+    if ((flags & DisplayHardware::SWAP_RECTANGLE) || 
+        (flags & DisplayHardware::BUFFER_PRESERVED)) 
+    {
+        // we can redraw only what's dirty, but since SWAP_RECTANGLE only
+        // takes a rectangle, we must make sure to update that whole
+        // rectangle in that case
+        if (flags & DisplayHardware::SWAP_RECTANGLE) {
+            // 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 {
+            // in the BUFFER_PRESERVED case, obviously, we can update only
+            // what's needed and nothing more.
+            // NOTE: this is NOT a common case, as preserving the backbuffer
+            // is costly and usually involves copying the whole update back.
+        }
+    } else {
+        if (flags & DisplayHardware::PARTIAL_UPDATES) {
+            // We need to redraw the rectangle that will be updated
+            // (pushed to the framebuffer).
+            // This is needed because PARTIAL_UPDATES only takes one
+            // rectangle instead of a region (see DisplayHardware::flip())
+            mDirtyRegion.set(mInvalidRegion.bounds());
+        } else {
+            // we need to redraw everything (the whole screen)
+            mDirtyRegion.set(hw.bounds());
+            mInvalidRegion = mDirtyRegion;
+        }
+    }
+
+    // compose all surfaces
+    composeSurfaces(mDirtyRegion);
+
+    // clear the dirty regions
+    mDirtyRegion.clear();
+}
+
+void SurfaceFlinger::composeSurfaces(const Region& dirty)
+{
+    if (UNLIKELY(!mWormholeRegion.isEmpty())) {
+        // should never happen unless the window manager has a bug
+        // draw something...
+        drawWormhole();
+    }
+    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 clip(dirty.intersect(layer->visibleRegionScreen));
+        if (!clip.isEmpty()) {
+            layer->draw(clip);
+        }
+    }
+}
+
+void SurfaceFlinger::unlockClients()
+{
+    const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
+    const size_t count = drawingLayers.size();
+    sp<LayerBase> const* const layers = drawingLayers.array();
+    for (size_t i=0 ; i<count ; ++i) {
+        const sp<LayerBase>& layer = layers[i];
+        layer->finishPageFlip();
+    }
+}
+
+void SurfaceFlinger::debugFlashRegions()
+{
+    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);
+    }
+
+    TextureManager::deactivateTextures();
+
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+    glDisable(GL_SCISSOR_TEST);
+
+    static int toggle = 0;
+    toggle = 1 - toggle;
+    if (toggle) {
+        glColor4f(1, 0, 1, 1);
+    } else {
+        glColor4f(1, 1, 0, 1);
+    }
+
+    Region::const_iterator it = mDirtyRegion.begin();
+    Region::const_iterator const end = mDirtyRegion.end();
+    while (it != end) {
+        const Rect& r = *it++;
+        GLfloat vertices[][2] = {
+                { r.left,  r.top },
+                { r.left,  r.bottom },
+                { r.right, r.bottom },
+                { r.right, r.top }
+        };
+        glVertexPointer(2, GL_FLOAT, 0, vertices);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+    }
+
+    if (mInvalidRegion.isEmpty()) {
+        mDirtyRegion.dump("mDirtyRegion");
+        mInvalidRegion.dump("mInvalidRegion");
+    }
+    hw.flip(mInvalidRegion);
+
+    if (mDebugRegion > 1)
+        usleep(mDebugRegion * 1000);
+
+    glEnable(GL_SCISSOR_TEST);
+    //mDirtyRegion.dump("mDirtyRegion");
+}
+
+void SurfaceFlinger::drawWormhole() const
+{
+    const Region region(mWormholeRegion.intersect(mDirtyRegion));
+    if (region.isEmpty())
+        return;
+
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const int32_t width = hw.getWidth();
+    const int32_t height = hw.getHeight();
+
+    glDisable(GL_BLEND);
+    glDisable(GL_DITHER);
+
+    if (LIKELY(!mDebugBackground)) {
+        glClearColor(0,0,0,0);
+        Region::const_iterator it = region.begin();
+        Region::const_iterator const end = region.end();
+        while (it != end) {
+            const Rect& r = *it++;
+            const GLint sy = height - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glClear(GL_COLOR_BUFFER_BIT);
+        }
+    } else {
+        const GLshort vertices[][2] = { { 0, 0 }, { width, 0 },
+                { width, height }, { 0, height }  };
+        const GLshort tcoords[][2] = { { 0, 0 }, { 1, 0 },  { 1, 1 }, { 0, 1 } };
+        glVertexPointer(2, GL_SHORT, 0, vertices);
+        glTexCoordPointer(2, GL_SHORT, 0, tcoords);
+        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+#if defined(GL_OES_EGL_image_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);
+        glMatrixMode(GL_TEXTURE);
+        glLoadIdentity();
+        glScalef(width*(1.0f/32.0f), height*(1.0f/32.0f), 1);
+        Region::const_iterator it = region.begin();
+        Region::const_iterator const end = region.end();
+        while (it != end) {
+            const Rect& r = *it++;
+            const GLint sy = height - (r.top + r.height());
+            glScissor(r.left, sy, r.width(), r.height());
+            glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        }
+        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    }
+}
+
+void SurfaceFlinger::debugShowFPS() const
+{
+    static int mFrameCount;
+    static int mLastFrameCount = 0;
+    static nsecs_t mLastFpsTime = 0;
+    static float mFps = 0;
+    mFrameCount++;
+    nsecs_t now = systemTime();
+    nsecs_t diff = now - mLastFpsTime;
+    if (diff > ms2ns(250)) {
+        mFps =  ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
+        mLastFpsTime = now;
+        mLastFrameCount = mFrameCount;
+    }
+    // XXX: mFPS has the value we want
+ }
+
+status_t SurfaceFlinger::addLayer(const sp<LayerBase>& layer)
+{
+    Mutex::Autolock _l(mStateLock);
+    addLayer_l(layer);
+    setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+    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);
+    status_t err = purgatorizeLayer_l(layer);
+    if (err == NO_ERROR)
+        setTransactionFlags(eTransactionNeeded);
+    return err;
+}
+
+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;
+        return NO_ERROR;
+    }
+    return status_t(index);
+}
+
+status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
+{
+    // remove the layer from the main list (through a transaction).
+    ssize_t err = removeLayer_l(layerBase);
+
+    layerBase->onRemoved();
+
+    // 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 Client::destroySurface(),
+    // ~Client() and ~ISurface().
+    return (err == NAME_NOT_FOUND) ? status_t(NO_ERROR) : err;
+}
+
+status_t SurfaceFlinger::invalidateLayerVisibility(const sp<LayerBase>& layer)
+{
+    layer->forceVisibilityTransaction();
+    setTransactionFlags(eTraversalNeeded);
+    return NO_ERROR;
+}
+
+uint32_t SurfaceFlinger::getTransactionFlags(uint32_t flags)
+{
+    return android_atomic_and(~flags, &mTransactionFlags) & flags;
+}
+
+uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags)
+{
+    uint32_t old = android_atomic_or(flags, &mTransactionFlags);
+    if ((old & flags)==0) { // wake the server up
+        signalEvent();
+    }
+    return old;
+}
+
+void SurfaceFlinger::openGlobalTransaction()
+{
+    android_atomic_inc(&mTransactionCount);
+}
+
+void SurfaceFlinger::closeGlobalTransaction()
+{
+    if (android_atomic_dec(&mTransactionCount) == 1) {
+        signalEvent();
+
+        // if there is a transaction with a resize, wait for it to 
+        // take effect before returning.
+        Mutex::Autolock _l(mStateLock);
+        while (mResizeTransationPending) {
+            status_t err = mTransactionCV.waitRelative(mStateLock, s2ns(5));
+            if (CC_UNLIKELY(err != NO_ERROR)) {
+                // just in case something goes wrong in SF, return to the
+                // called after a few seconds.
+                LOGW_IF(err == TIMED_OUT, "closeGlobalTransaction timed out!");
+                mResizeTransationPending = false;
+                break;
+            }
+        }
+    }
+}
+
+status_t SurfaceFlinger::freezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.freezeDisplay = 1;
+    setTransactionFlags(eTransactionNeeded);
+
+    // flags is intended to communicate some sort of animation behavior
+    // (for instance fading)
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::unfreezeDisplay(DisplayID dpy, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    mCurrentState.freezeDisplay = 0;
+    setTransactionFlags(eTransactionNeeded);
+
+    // flags is intended to communicate some sort of animation behavior
+    // (for instance fading)
+    return NO_ERROR;
+}
+
+int SurfaceFlinger::setOrientation(DisplayID dpy, 
+        int orientation, uint32_t flags)
+{
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mStateLock);
+    if (mCurrentState.orientation != orientation) {
+        if (uint32_t(orientation)<=eOrientation270 || orientation==42) {
+            mCurrentState.orientationType = flags;
+            mCurrentState.orientation = orientation;
+            setTransactionFlags(eTransactionNeeded);
+            mTransactionCV.wait(mStateLock);
+        } else {
+            orientation = BAD_VALUE;
+        }
+    }
+    return orientation;
+}
+
+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)
+{
+    sp<LayerBaseClient> layer;
+    sp<LayerBaseClient::Surface> surfaceHandle;
+
+    if (int32_t(w|h) < 0) {
+        LOGE("createSurface() failed, w or h is negative (w=%d, h=%d)",
+                int(w), int(h));
+        return surfaceHandle;
+    }
+    
+    //LOGD("createSurface for pid %d (%d x %d)", pid, w, h);
+    sp<Layer> normalLayer;
+    switch (flags & eFXSurfaceMask) {
+        case eFXSurfaceNormal:
+            if (UNLIKELY(flags & ePushBuffers)) {
+                layer = createPushBuffersSurface(client, d, w, h, flags);
+            } else {
+                normalLayer = createNormalSurface(client, d, w, h, flags, format);
+                layer = normalLayer;
+            }
+            break;
+        case eFXSurfaceBlur:
+            layer = createBlurSurface(client, d, w, h, flags);
+            break;
+        case eFXSurfaceDim:
+            layer = createDimSurface(client, d, w, h, flags);
+            break;
+    }
+
+    if (layer != 0) {
+        layer->initStates(w, h, flags);
+        layer->setName(name);
+        ssize_t token = addClientLayer(client, layer);
+
+        surfaceHandle = layer->getSurface();
+        if (surfaceHandle != 0) { 
+            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<Layer> SurfaceFlinger::createNormalSurface(
+        const sp<Client>& client, DisplayID display,
+        uint32_t w, uint32_t h, uint32_t flags,
+        PixelFormat& format)
+{
+    // initialize the surfaces
+    switch (format) { // TODO: take h/w into account
+    case PIXEL_FORMAT_TRANSPARENT:
+    case PIXEL_FORMAT_TRANSLUCENT:
+        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;
+    }
+
+#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)) {
+        LOGE("createNormalSurfaceLocked() failed (%s)", strerror(-err));
+        layer.clear();
+    }
+    return layer;
+}
+
+sp<LayerBlur> SurfaceFlinger::createBlurSurface(
+        const sp<Client>& client, DisplayID display,
+        uint32_t w, uint32_t h, uint32_t flags)
+{
+    sp<LayerBlur> layer = new LayerBlur(this, display, client);
+    layer->initStates(w, h, flags);
+    return layer;
+}
+
+sp<LayerDim> SurfaceFlinger::createDimSurface(
+        const sp<Client>& client, DisplayID display,
+        uint32_t w, uint32_t h, uint32_t flags)
+{
+    sp<LayerDim> layer = new LayerDim(this, display, client);
+    layer->initStates(w, h, flags);
+    return layer;
+}
+
+sp<LayerBuffer> SurfaceFlinger::createPushBuffersSurface(
+        const sp<Client>& client, DisplayID display,
+        uint32_t w, uint32_t h, uint32_t flags)
+{
+    sp<LayerBuffer> layer = new LayerBuffer(this, display, client);
+    layer->initStates(w, h, flags);
+    return layer;
+}
+
+status_t SurfaceFlinger::removeSurface(const sp<Client>& client, SurfaceID sid)
+{
+    /*
+     * called by the window manager, when a surface should be marked for
+     * destruction.
+     * 
+     * The surface is removed from the current and drawing lists, but placed
+     * in the purgatory queue, so it's not destroyed right-away (we need
+     * to wait for all client's references to go away first).
+     */
+
+    status_t err = NAME_NOT_FOUND;
+    Mutex::Autolock _l(mStateLock);
+    sp<LayerBaseClient> layer = client->getLayerUser(sid);
+    if (layer != 0) {
+        err = purgatorizeLayer_l(layer);
+        if (err == NO_ERROR) {
+            setTransactionFlags(eTransactionNeeded);
+        }
+    }
+    return err;
+}
+
+status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
+{
+    // called by ~ISurface() when all references are gone
+    
+    class MessageDestroySurface : public MessageBase {
+        SurfaceFlinger* flinger;
+        sp<LayerBaseClient> layer;
+    public:
+        MessageDestroySurface(
+                SurfaceFlinger* flinger, const sp<LayerBaseClient>& layer)
+            : flinger(flinger), layer(layer) { }
+        virtual bool handler() {
+            sp<LayerBaseClient> l(layer);
+            layer.clear(); // clear it outside of the lock;
+            Mutex::Autolock _l(flinger->mStateLock);
+            /*
+             * remove the layer from the current list -- chances are that it's 
+             * not in the list anyway, because it should have been removed 
+             * already upon request of the client (eg: window manager). 
+             * However, a buggy client could have not done that.
+             * Since we know we don't have any more clients, we don't need
+             * to use the purgatory.
+             */
+            status_t err = flinger->removeLayer_l(l);
+            LOGE_IF(err<0 && err != NAME_NOT_FOUND,
+                    "error removing layer=%p (%s)", l.get(), strerror(-err));
+            return true;
+        }
+    };
+
+    postMessageAsync( new MessageDestroySurface(this, layer) );
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::setClientState(
+        const sp<Client>& client,
+        int32_t count,
+        const layer_state_t* states)
+{
+    Mutex::Autolock _l(mStateLock);
+    uint32_t flags = 0;
+    for (int i=0 ; i<count ; i++) {
+        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) {
+                if (layer->setPosition(s.x, s.y))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eLayerChanged) {
+                ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
+                if (layer->setLayer(s.z)) {
+                    mCurrentState.layersSortedByZ.removeAt(idx);
+                    mCurrentState.layersSortedByZ.add(layer);
+                    // we need traversal (state changed)
+                    // AND transaction (list changed)
+                    flags |= eTransactionNeeded|eTraversalNeeded;
+                }
+            }
+            if (what & eSizeChanged) {
+                if (layer->setSize(s.w, s.h)) {
+                    flags |= eTraversalNeeded;
+                    mResizeTransationPending = true;
+                }
+            }
+            if (what & eAlphaChanged) {
+                if (layer->setAlpha(uint8_t(255.0f*s.alpha+0.5f)))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eMatrixChanged) {
+                if (layer->setMatrix(s.matrix))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eTransparentRegionChanged) {
+                if (layer->setTransparentRegionHint(s.transparentRegion))
+                    flags |= eTraversalNeeded;
+            }
+            if (what & eVisibilityChanged) {
+                if (layer->setFlags(s.flags, s.mask))
+                    flags |= eTraversalNeeded;
+            }
+        }
+    }
+    if (flags) {
+        setTransactionFlags(flags);
+    }
+    return NO_ERROR;
+}
+
+void SurfaceFlinger::screenReleased(int dpy)
+{
+    // this may be called by a signal handler, we can't do too much in here
+    android_atomic_or(eConsoleReleased, &mConsoleSignals);
+    signalEvent();
+}
+
+void SurfaceFlinger::screenAcquired(int dpy)
+{
+    // this may be called by a signal handler, we can't do too much in here
+    android_atomic_or(eConsoleAcquired, &mConsoleSignals);
+    signalEvent();
+}
+
+status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 1024;
+    char buffer[SIZE];
+    String8 result;
+    if (!mDump.checkCalling()) {
+        snprintf(buffer, SIZE, "Permission Denial: "
+                "can't dump SurfaceFlinger from pid=%d, uid=%d\n",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        result.append(buffer);
+    } else {
+
+        // figure out if we're stuck somewhere
+        const nsecs_t now = systemTime();
+        const nsecs_t inSwapBuffers(mDebugInSwapBuffers);
+        const nsecs_t inTransaction(mDebugInTransaction);
+        nsecs_t inSwapBuffersDuration = (inSwapBuffers) ? now-inSwapBuffers : 0;
+        nsecs_t inTransactionDuration = (inTransaction) ? now-inTransaction : 0;
+
+        // Try to get the main lock, but don't insist if we can't
+        // (this would indicate SF is stuck, but we want to be able to
+        // print something in dumpsys).
+        int retry = 3;
+        while (mStateLock.tryLock()<0 && --retry>=0) {
+            usleep(1000000);
+        }
+        const bool locked(retry >= 0);
+        if (!locked) {
+            snprintf(buffer, SIZE, 
+                    "SurfaceFlinger appears to be unresponsive, "
+                    "dumping anyways (no locks held)\n");
+            result.append(buffer);
+        }
+
+        const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
+        const size_t count = currentLayers.size();
+        for (size_t i=0 ; i<count ; i++) {
+            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,
+                "  display frozen: %s, freezeCount=%d, orientation=%d, canDraw=%d\n",
+                mFreezeDisplay?"yes":"no", mFreezeCount,
+                mCurrentState.orientation, hw.canDraw());
+        result.append(buffer);
+        snprintf(buffer, SIZE,
+                "  last eglSwapBuffers() time: %f us\n"
+                "  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);
+        }
+
+        const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
+        alloc.dump(result);
+
+        if (locked) {
+            mStateLock.unlock();
+        }
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch (code) {
+        case CREATE_CONNECTION:
+        case OPEN_GLOBAL_TRANSACTION:
+        case CLOSE_GLOBAL_TRANSACTION:
+        case SET_ORIENTATION:
+        case FREEZE_DISPLAY:
+        case UNFREEZE_DISPLAY:
+        case BOOT_FINISHED:
+        case TURN_ELECTRON_BEAM_OFF:
+        case TURN_ELECTRON_BEAM_ON:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int uid = ipc->getCallingUid();
+            if ((uid != AID_GRAPHICS) && !mAccessSurfaceFlinger.check(pid, uid)) {
+                LOGE("Permission Denial: "
+                        "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+                return PERMISSION_DENIED;
+            }
+            break;
+        }
+        case CAPTURE_SCREEN:
+        {
+            // codes that require permission check
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int uid = ipc->getCallingUid();
+            if ((uid != AID_GRAPHICS) && !mReadFramebuffer.check(pid, uid)) {
+                LOGE("Permission Denial: "
+                        "can't read framebuffer pid=%d, uid=%d", pid, uid);
+                return PERMISSION_DENIED;
+            }
+            break;
+        }
+    }
+
+    status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags);
+    if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
+        CHECK_INTERFACE(ISurfaceComposer, data, reply);
+        if (UNLIKELY(!mHardwareTest.checkCalling())) {
+            IPCThreadState* ipc = IPCThreadState::self();
+            const int pid = ipc->getCallingPid();
+            const int uid = ipc->getCallingUid();
+            LOGE("Permission Denial: "
+                    "can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
+            return PERMISSION_DENIED;
+        }
+        int n;
+        switch (code) {
+            case 1000: // SHOW_CPU, NOT SUPPORTED ANYMORE
+            case 1001: // SHOW_FPS, NOT SUPPORTED ANYMORE
+                return NO_ERROR;
+            case 1002:  // SHOW_UPDATES
+                n = data.readInt32();
+                mDebugRegion = n ? n : (mDebugRegion ? 0 : 1);
+                return NO_ERROR;
+            case 1003:  // SHOW_BACKGROUND
+                n = data.readInt32();
+                mDebugBackground = n ? 1 : 0;
+                return NO_ERROR;
+            case 1004:{ // repaint everything
+                Mutex::Autolock _l(mStateLock);
+                const DisplayHardware& hw(graphicPlane(0).displayHardware());
+                mDirtyRegion.set(hw.bounds()); // careful that's not thread-safe
+                signalEvent();
+                return NO_ERROR;
+            }
+            case 1005:{ // force transaction
+                setTransactionFlags(eTransactionNeeded|eTraversalNeeded);
+                return NO_ERROR;
+            }
+            case 1006:{ // enable/disable GraphicLog
+                int enabled = data.readInt32();
+                GraphicLog::getInstance().setEnabled(enabled);
+                return NO_ERROR;
+            }
+            case 1007: // set mFreezeCount
+                mFreezeCount = data.readInt32();
+                mFreezeDisplayTime = 0;
+                return NO_ERROR;
+            case 1010:  // interrogate.
+                reply->writeInt32(0);
+                reply->writeInt32(0);
+                reply->writeInt32(mDebugRegion);
+                reply->writeInt32(mDebugBackground);
+                return NO_ERROR;
+            case 1013: {
+                Mutex::Autolock _l(mStateLock);
+                const DisplayHardware& hw(graphicPlane(0).displayHardware());
+                reply->writeInt32(hw.getPageFlipCount());
+            }
+            return NO_ERROR;
+        }
+    }
+    return err;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::renderScreenToTextureLocked(DisplayID dpy,
+        GLuint* textureName, GLfloat* uOut, GLfloat* vOut)
+{
+    if (!GLExtensions::getInstance().haveFramebufferObject())
+        return INVALID_OPERATION;
+
+    // get screen geometry
+    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
+    const uint32_t hw_w = hw.getWidth();
+    const uint32_t hw_h = hw.getHeight();
+    GLfloat u = 1;
+    GLfloat v = 1;
+
+    // make sure to clear all GL error flags
+    while ( glGetError() != GL_NO_ERROR ) ;
+
+    // create a FBO
+    GLuint name, tname;
+    glGenTextures(1, &tname);
+    glBindTexture(GL_TEXTURE_2D, tname);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+            hw_w, hw_h, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+    if (glGetError() != GL_NO_ERROR) {
+        while ( glGetError() != GL_NO_ERROR ) ;
+        GLint tw = (2 << (31 - clz(hw_w)));
+        GLint th = (2 << (31 - clz(hw_h)));
+        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
+                tw, th, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
+        u = GLfloat(hw_w) / tw;
+        v = GLfloat(hw_h) / th;
+    }
+    glGenFramebuffersOES(1, &name);
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+
+    // redraw the screen entirely...
+    glClearColor(0,0,0,1);
+    glClear(GL_COLOR_BUFFER_BIT);
+    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]);
+        layer->drawForSreenShot();
+    }
+
+    // back to main framebuffer
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+    glDisable(GL_SCISSOR_TEST);
+    glDeleteFramebuffersOES(1, &name);
+
+    *textureName = tname;
+    *uOut = u;
+    *vOut = v;
+    return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::electronBeamOffAnimationImplLocked()
+{
+    status_t result = PERMISSION_DENIED;
+
+    if (!GLExtensions::getInstance().haveFramebufferObject())
+        return INVALID_OPERATION;
+
+    // get screen geometry
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t hw_w = hw.getWidth();
+    const uint32_t hw_h = hw.getHeight();
+    const Region screenBounds(hw.bounds());
+
+    GLfloat u, v;
+    GLuint tname;
+    result = renderScreenToTextureLocked(0, &tname, &u, &v);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
+    GLfloat vtx[8];
+    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
+    glEnable(GL_TEXTURE_2D);
+    glBindTexture(GL_TEXTURE_2D, tname);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glVertexPointer(2, GL_FLOAT, 0, vtx);
+
+    class s_curve_interpolator {
+        const float nbFrames, s, v;
+    public:
+        s_curve_interpolator(int nbFrames, float s)
+        : nbFrames(1.0f / (nbFrames-1)), s(s),
+          v(1.0f + expf(-s + 0.5f*s)) {
+        }
+        float operator()(int f) {
+            const float x = f * nbFrames;
+            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
+        }
+    };
+
+    class v_stretch {
+        const GLfloat hw_w, hw_h;
+    public:
+        v_stretch(uint32_t hw_w, uint32_t hw_h)
+        : hw_w(hw_w), hw_h(hw_h) {
+        }
+        void operator()(GLfloat* vtx, float v) {
+            const GLfloat w = hw_w + (hw_w * v);
+            const GLfloat h = hw_h - (hw_h * v);
+            const GLfloat x = (hw_w - w) * 0.5f;
+            const GLfloat y = (hw_h - h) * 0.5f;
+            vtx[0] = x;         vtx[1] = y;
+            vtx[2] = x;         vtx[3] = y + h;
+            vtx[4] = x + w;     vtx[5] = y + h;
+            vtx[6] = x + w;     vtx[7] = y;
+        }
+    };
+
+    class h_stretch {
+        const GLfloat hw_w, hw_h;
+    public:
+        h_stretch(uint32_t hw_w, uint32_t hw_h)
+        : hw_w(hw_w), hw_h(hw_h) {
+        }
+        void operator()(GLfloat* vtx, float v) {
+            const GLfloat w = hw_w - (hw_w * v);
+            const GLfloat h = 1.0f;
+            const GLfloat x = (hw_w - w) * 0.5f;
+            const GLfloat y = (hw_h - h) * 0.5f;
+            vtx[0] = x;         vtx[1] = y;
+            vtx[2] = x;         vtx[3] = y + h;
+            vtx[4] = x + w;     vtx[5] = y + h;
+            vtx[6] = x + w;     vtx[7] = y;
+        }
+    };
+
+    // the full animation is 24 frames
+    const int nbFrames = 12;
+    s_curve_interpolator itr(nbFrames, 7.5f);
+    s_curve_interpolator itg(nbFrames, 8.0f);
+    s_curve_interpolator itb(nbFrames, 8.5f);
+
+    v_stretch vverts(hw_w, hw_h);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE);
+    for (int i=0 ; i<nbFrames ; i++) {
+        float x, y, w, h;
+        const float vr = itr(i);
+        const float vg = itg(i);
+        const float vb = itb(i);
+
+        // clear screen
+        glColorMask(1,1,1,1);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glEnable(GL_TEXTURE_2D);
+
+        // draw the red plane
+        vverts(vtx, vr);
+        glColorMask(1,0,0,1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the green plane
+        vverts(vtx, vg);
+        glColorMask(0,1,0,1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the blue plane
+        vverts(vtx, vb);
+        glColorMask(0,0,1,1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the white highlight (we use the last vertices)
+        glDisable(GL_TEXTURE_2D);
+        glColorMask(1,1,1,1);
+        glColor4f(vg, vg, vg, 1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        hw.flip(screenBounds);
+    }
+
+    h_stretch hverts(hw_w, hw_h);
+    glDisable(GL_BLEND);
+    glDisable(GL_TEXTURE_2D);
+    glColorMask(1,1,1,1);
+    for (int i=0 ; i<nbFrames ; i++) {
+        const float v = itg(i);
+        hverts(vtx, v);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glColor4f(1-v, 1-v, 1-v, 1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        hw.flip(screenBounds);
+    }
+
+    glColorMask(1,1,1,1);
+    glEnable(GL_SCISSOR_TEST);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDeleteTextures(1, &tname);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::electronBeamOnAnimationImplLocked()
+{
+    status_t result = PERMISSION_DENIED;
+
+    if (!GLExtensions::getInstance().haveFramebufferObject())
+        return INVALID_OPERATION;
+
+
+    // get screen geometry
+    const DisplayHardware& hw(graphicPlane(0).displayHardware());
+    const uint32_t hw_w = hw.getWidth();
+    const uint32_t hw_h = hw.getHeight();
+    const Region screenBounds(hw.bounds());
+
+    GLfloat u, v;
+    GLuint tname;
+    result = renderScreenToTextureLocked(0, &tname, &u, &v);
+    if (result != NO_ERROR) {
+        return result;
+    }
+
+    // back to main framebuffer
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+    glDisable(GL_SCISSOR_TEST);
+
+    GLfloat vtx[8];
+    const GLfloat texCoords[4][2] = { {0,v}, {0,0}, {u,0}, {u,v} };
+    glEnable(GL_TEXTURE_2D);
+    glBindTexture(GL_TEXTURE_2D, tname);
+    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+    glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glVertexPointer(2, GL_FLOAT, 0, vtx);
+
+    class s_curve_interpolator {
+        const float nbFrames, s, v;
+    public:
+        s_curve_interpolator(int nbFrames, float s)
+        : nbFrames(1.0f / (nbFrames-1)), s(s),
+          v(1.0f + expf(-s + 0.5f*s)) {
+        }
+        float operator()(int f) {
+            const float x = f * nbFrames;
+            return ((1.0f/(1.0f + expf(-x*s + 0.5f*s))) - 0.5f) * v + 0.5f;
+        }
+    };
+
+    class v_stretch {
+        const GLfloat hw_w, hw_h;
+    public:
+        v_stretch(uint32_t hw_w, uint32_t hw_h)
+        : hw_w(hw_w), hw_h(hw_h) {
+        }
+        void operator()(GLfloat* vtx, float v) {
+            const GLfloat w = hw_w + (hw_w * v);
+            const GLfloat h = hw_h - (hw_h * v);
+            const GLfloat x = (hw_w - w) * 0.5f;
+            const GLfloat y = (hw_h - h) * 0.5f;
+            vtx[0] = x;         vtx[1] = y;
+            vtx[2] = x;         vtx[3] = y + h;
+            vtx[4] = x + w;     vtx[5] = y + h;
+            vtx[6] = x + w;     vtx[7] = y;
+        }
+    };
+
+    class h_stretch {
+        const GLfloat hw_w, hw_h;
+    public:
+        h_stretch(uint32_t hw_w, uint32_t hw_h)
+        : hw_w(hw_w), hw_h(hw_h) {
+        }
+        void operator()(GLfloat* vtx, float v) {
+            const GLfloat w = hw_w - (hw_w * v);
+            const GLfloat h = 1.0f;
+            const GLfloat x = (hw_w - w) * 0.5f;
+            const GLfloat y = (hw_h - h) * 0.5f;
+            vtx[0] = x;         vtx[1] = y;
+            vtx[2] = x;         vtx[3] = y + h;
+            vtx[4] = x + w;     vtx[5] = y + h;
+            vtx[6] = x + w;     vtx[7] = y;
+        }
+    };
+
+    // the full animation is 12 frames
+    int nbFrames = 8;
+    s_curve_interpolator itr(nbFrames, 7.5f);
+    s_curve_interpolator itg(nbFrames, 8.0f);
+    s_curve_interpolator itb(nbFrames, 8.5f);
+
+    h_stretch hverts(hw_w, hw_h);
+    glDisable(GL_BLEND);
+    glDisable(GL_TEXTURE_2D);
+    glColorMask(1,1,1,1);
+    for (int i=nbFrames-1 ; i>=0 ; i--) {
+        const float v = itg(i);
+        hverts(vtx, v);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glColor4f(1-v, 1-v, 1-v, 1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+        hw.flip(screenBounds);
+    }
+
+    nbFrames = 4;
+    v_stretch vverts(hw_w, hw_h);
+    glEnable(GL_BLEND);
+    glBlendFunc(GL_ONE, GL_ONE);
+    for (int i=nbFrames-1 ; i>=0 ; i--) {
+        float x, y, w, h;
+        const float vr = itr(i);
+        const float vg = itg(i);
+        const float vb = itb(i);
+
+        // clear screen
+        glColorMask(1,1,1,1);
+        glClear(GL_COLOR_BUFFER_BIT);
+        glEnable(GL_TEXTURE_2D);
+
+        // draw the red plane
+        vverts(vtx, vr);
+        glColorMask(1,0,0,1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the green plane
+        vverts(vtx, vg);
+        glColorMask(0,1,0,1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        // draw the blue plane
+        vverts(vtx, vb);
+        glColorMask(0,0,1,1);
+        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+        hw.flip(screenBounds);
+    }
+
+    glColorMask(1,1,1,1);
+    glEnable(GL_SCISSOR_TEST);
+    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+    glDeleteTextures(1, &tname);
+
+    return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::turnElectronBeamOffImplLocked(int32_t mode)
+{
+    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
+    if (!hw.canDraw()) {
+        // we're already off
+        return NO_ERROR;
+    }
+    if (mode & ISurfaceComposer::eElectronBeamAnimationOff) {
+        electronBeamOffAnimationImplLocked();
+    }
+
+    // always clear the whole screen at the end of the animation
+    glClearColor(0,0,0,1);
+    glDisable(GL_SCISSOR_TEST);
+    glClear(GL_COLOR_BUFFER_BIT);
+    glEnable(GL_SCISSOR_TEST);
+    hw.flip( Region(hw.bounds()) );
+
+    hw.setCanDraw(false);
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::turnElectronBeamOff(int32_t mode)
+{
+    class MessageTurnElectronBeamOff : public MessageBase {
+        SurfaceFlinger* flinger;
+        int32_t mode;
+        status_t result;
+    public:
+        MessageTurnElectronBeamOff(SurfaceFlinger* flinger, int32_t mode)
+            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
+        }
+        status_t getResult() const {
+            return result;
+        }
+        virtual bool handler() {
+            Mutex::Autolock _l(flinger->mStateLock);
+            result = flinger->turnElectronBeamOffImplLocked(mode);
+            return true;
+        }
+    };
+
+    sp<MessageBase> msg = new MessageTurnElectronBeamOff(this, mode);
+    status_t res = postMessageSync(msg);
+    if (res == NO_ERROR) {
+        res = static_cast<MessageTurnElectronBeamOff*>( msg.get() )->getResult();
+
+        // work-around: when the power-manager calls us we activate the
+        // animation. eventually, the "on" animation will be called
+        // by the power-manager itself
+        mElectronBeamAnimationMode = mode;
+    }
+    return res;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::turnElectronBeamOnImplLocked(int32_t mode)
+{
+    DisplayHardware& hw(graphicPlane(0).editDisplayHardware());
+    if (hw.canDraw()) {
+        // we're already on
+        return NO_ERROR;
+    }
+    if (mode & ISurfaceComposer::eElectronBeamAnimationOn) {
+        electronBeamOnAnimationImplLocked();
+    }
+    hw.setCanDraw(true);
+
+    // make sure to redraw the whole screen when the animation is done
+    mDirtyRegion.set(hw.bounds());
+    signalEvent();
+
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::turnElectronBeamOn(int32_t mode)
+{
+    class MessageTurnElectronBeamOn : public MessageBase {
+        SurfaceFlinger* flinger;
+        int32_t mode;
+        status_t result;
+    public:
+        MessageTurnElectronBeamOn(SurfaceFlinger* flinger, int32_t mode)
+            : flinger(flinger), mode(mode), result(PERMISSION_DENIED) {
+        }
+        status_t getResult() const {
+            return result;
+        }
+        virtual bool handler() {
+            Mutex::Autolock _l(flinger->mStateLock);
+            result = flinger->turnElectronBeamOnImplLocked(mode);
+            return true;
+        }
+    };
+
+    postMessageAsync( new MessageTurnElectronBeamOn(this, mode) );
+    return NO_ERROR;
+}
+
+// ---------------------------------------------------------------------------
+
+status_t SurfaceFlinger::captureScreenImplLocked(DisplayID dpy,
+        sp<IMemoryHeap>* heap,
+        uint32_t* w, uint32_t* h, PixelFormat* f,
+        uint32_t sw, uint32_t sh)
+{
+    status_t result = PERMISSION_DENIED;
+
+    // only one display supported for now
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    if (!GLExtensions::getInstance().haveFramebufferObject())
+        return INVALID_OPERATION;
+
+    // get screen geometry
+    const DisplayHardware& hw(graphicPlane(dpy).displayHardware());
+    const uint32_t hw_w = hw.getWidth();
+    const uint32_t hw_h = hw.getHeight();
+
+    if ((sw > hw_w) || (sh > hw_h))
+        return BAD_VALUE;
+
+    sw = (!sw) ? hw_w : sw;
+    sh = (!sh) ? hw_h : sh;
+    const size_t size = sw * sh * 4;
+
+    // make sure to clear all GL error flags
+    while ( glGetError() != GL_NO_ERROR ) ;
+
+    // create a FBO
+    GLuint name, tname;
+    glGenRenderbuffersOES(1, &tname);
+    glBindRenderbufferOES(GL_RENDERBUFFER_OES, tname);
+    glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_RGBA8_OES, sw, sh);
+    glGenFramebuffersOES(1, &name);
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES,
+            GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, tname);
+
+    GLenum status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+    if (status == GL_FRAMEBUFFER_COMPLETE_OES) {
+
+        // invert everything, b/c glReadPixel() below will invert the FB
+        glViewport(0, 0, sw, sh);
+        glMatrixMode(GL_PROJECTION);
+        glPushMatrix();
+        glLoadIdentity();
+        glOrthof(0, hw_w, 0, hw_h, 0, 1);
+        glMatrixMode(GL_MODELVIEW);
+
+        // redraw the screen entirely...
+        glClearColor(0,0,0,1);
+        glClear(GL_COLOR_BUFFER_BIT);
+        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]);
+            layer->drawForSreenShot();
+        }
+
+        // XXX: this is needed on tegra
+        glScissor(0, 0, sw, sh);
+
+        // check for errors and return screen capture
+        if (glGetError() != GL_NO_ERROR) {
+            // error while rendering
+            result = INVALID_OPERATION;
+        } else {
+            // allocate shared memory large enough to hold the
+            // screen capture
+            sp<MemoryHeapBase> base(
+                    new MemoryHeapBase(size, 0, "screen-capture") );
+            void* const ptr = base->getBase();
+            if (ptr) {
+                // capture the screen with glReadPixels()
+                glReadPixels(0, 0, sw, sh, GL_RGBA, GL_UNSIGNED_BYTE, ptr);
+                if (glGetError() == GL_NO_ERROR) {
+                    *heap = base;
+                    *w = sw;
+                    *h = sh;
+                    *f = PIXEL_FORMAT_RGBA_8888;
+                    result = NO_ERROR;
+                }
+            } else {
+                result = NO_MEMORY;
+            }
+        }
+
+        glEnable(GL_SCISSOR_TEST);
+        glViewport(0, 0, hw_w, hw_h);
+        glMatrixMode(GL_PROJECTION);
+        glPopMatrix();
+        glMatrixMode(GL_MODELVIEW);
+
+
+    } else {
+        result = BAD_VALUE;
+    }
+
+    // release FBO resources
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+    glDeleteRenderbuffersOES(1, &tname);
+    glDeleteFramebuffersOES(1, &name);
+    return result;
+}
+
+
+status_t SurfaceFlinger::captureScreen(DisplayID dpy,
+        sp<IMemoryHeap>* heap,
+        uint32_t* width, uint32_t* height, PixelFormat* format,
+        uint32_t sw, uint32_t sh)
+{
+    // only one display supported for now
+    if (UNLIKELY(uint32_t(dpy) >= DISPLAY_COUNT))
+        return BAD_VALUE;
+
+    if (!GLExtensions::getInstance().haveFramebufferObject())
+        return INVALID_OPERATION;
+
+    class MessageCaptureScreen : public MessageBase {
+        SurfaceFlinger* flinger;
+        DisplayID dpy;
+        sp<IMemoryHeap>* heap;
+        uint32_t* w;
+        uint32_t* h;
+        PixelFormat* f;
+        uint32_t sw;
+        uint32_t sh;
+        status_t result;
+    public:
+        MessageCaptureScreen(SurfaceFlinger* flinger, DisplayID dpy,
+                sp<IMemoryHeap>* heap, uint32_t* w, uint32_t* h, PixelFormat* f,
+                uint32_t sw, uint32_t sh)
+            : flinger(flinger), dpy(dpy),
+              heap(heap), w(w), h(h), f(f), sw(sw), sh(sh), result(PERMISSION_DENIED)
+        {
+        }
+        status_t getResult() const {
+            return result;
+        }
+        virtual bool handler() {
+            Mutex::Autolock _l(flinger->mStateLock);
+
+            // if we have secure windows, never allow the screen capture
+            if (flinger->mSecureFrameBuffer)
+                return true;
+
+            result = flinger->captureScreenImplLocked(dpy,
+                    heap, w, h, f, sw, sh);
+
+            return true;
+        }
+    };
+
+    sp<MessageBase> msg = new MessageCaptureScreen(this,
+            dpy, heap, width, height, format, sw, sh);
+    status_t res = postMessageSync(msg);
+    if (res == NO_ERROR) {
+        res = static_cast<MessageCaptureScreen*>( msg.get() )->getResult();
+    }
+    return res;
+}
+
+// ---------------------------------------------------------------------------
+
+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));
+
+    mCblkHeap = new MemoryHeapBase(cblksize, 0,
+            "SurfaceFlinger Client control-block");
+
+    ctrlblk = static_cast<SharedClient *>(mCblkHeap->getBase());
+    if (ctrlblk) { // construct the shared structure in-place.
+        new(ctrlblk) SharedClient;
+    }
+}
+
+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.
+     */
+}
+
+status_t UserClient::initCheck() const {
+    return ctrlblk == 0 ? NO_INIT : NO_ERROR;
+}
+
+void UserClient::detachLayer(const Layer* layer)
+{
+    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));
+        }
+    }
+}
+
+sp<IMemoryHeap> UserClient::getControlBlock() const {
+    return mCblkHeap;
+}
+
+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;
+}
+
+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 0;
+}
+status_t UserClient::destroySurface(SurfaceID sid) {
+    return INVALID_OPERATION;
+}
+status_t UserClient::setState(int32_t count, const layer_state_t* states) {
+    return INVALID_OPERATION;
+}
+
+// ---------------------------------------------------------------------------
+
+GraphicPlane::GraphicPlane()
+    : mHw(0)
+{
+}
+
+GraphicPlane::~GraphicPlane() {
+    delete mHw;
+}
+
+bool GraphicPlane::initialized() const {
+    return mHw ? true : false;
+}
+
+int GraphicPlane::getWidth() const {
+    return mWidth;
+}
+
+int GraphicPlane::getHeight() const {
+    return mHeight;
+}
+
+void GraphicPlane::setDisplayHardware(DisplayHardware *hw)
+{
+    mHw = hw;
+
+    // initialize the display orientation transform.
+    // it's a constant that should come from the display driver.
+    int displayOrientation = ISurfaceComposer::eOrientationDefault;
+    char property[PROPERTY_VALUE_MAX];
+    if (property_get("ro.sf.hwrotation", property, NULL) > 0) {
+        //displayOrientation
+        switch (atoi(property)) {
+        case 90:
+            displayOrientation = ISurfaceComposer::eOrientation90;
+            break;
+        case 270:
+            displayOrientation = ISurfaceComposer::eOrientation270;
+            break;
+        }
+    }
+
+    const float w = hw->getWidth();
+    const float h = hw->getHeight();
+    GraphicPlane::orientationToTransfrom(displayOrientation, w, h,
+            &mDisplayTransform);
+    if (displayOrientation & ISurfaceComposer::eOrientationSwapMask) {
+        mDisplayWidth = h;
+        mDisplayHeight = w;
+    } else {
+        mDisplayWidth = w;
+        mDisplayHeight = h;
+    }
+
+    setOrientation(ISurfaceComposer::eOrientationDefault);
+}
+
+status_t GraphicPlane::orientationToTransfrom(
+        int orientation, int w, int h, Transform* tr)
+{
+    uint32_t flags = 0;
+    switch (orientation) {
+    case ISurfaceComposer::eOrientationDefault:
+        flags = Transform::ROT_0;
+        break;
+    case ISurfaceComposer::eOrientation90:
+        flags = Transform::ROT_90;
+        break;
+    case ISurfaceComposer::eOrientation180:
+        flags = Transform::ROT_180;
+        break;
+    case ISurfaceComposer::eOrientation270:
+        flags = Transform::ROT_270;
+        break;
+    default:
+        return BAD_VALUE;
+    }
+    tr->set(flags, w, h);
+    return NO_ERROR;
+}
+
+status_t GraphicPlane::setOrientation(int orientation)
+{
+    // If the rotation can be handled in hardware, this is where
+    // the magic should happen.
+
+    const DisplayHardware& hw(displayHardware());
+    const float w = mDisplayWidth;
+    const float h = mDisplayHeight;
+    mWidth = int(w);
+    mHeight = int(h);
+
+    Transform orientationTransform;
+    GraphicPlane::orientationToTransfrom(orientation, w, h,
+            &orientationTransform);
+    if (orientation & ISurfaceComposer::eOrientationSwapMask) {
+        mWidth = int(h);
+        mHeight = int(w);
+    }
+
+    mOrientation = orientation;
+    mGlobalTransform = mDisplayTransform * orientationTransform;
+    return NO_ERROR;
+}
+
+const DisplayHardware& GraphicPlane::displayHardware() const {
+    return *mHw;
+}
+
+DisplayHardware& GraphicPlane::editDisplayHardware() {
+    return *mHw;
+}
+
+const Transform& GraphicPlane::transform() const {
+    return mGlobalTransform;
+}
+
+EGLDisplay GraphicPlane::getEGLDisplay() const {
+    return mHw->getEGLDisplay();
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
new file mode 100644
index 0000000..4262175
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -0,0 +1,444 @@
+/*
+ * 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_SURFACE_FLINGER_H
+#define ANDROID_SURFACE_FLINGER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Atomic.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IMemory.h>
+#include <binder/Permission.h>
+#include <binder/BinderService.h>
+
+#include <ui/PixelFormat.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+
+#include "Barrier.h"
+#include "Layer.h"
+
+#include "MessageQueue.h"
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class Client;
+class DisplayHardware;
+class FreezeLock;
+class Layer;
+class LayerBlur;
+class LayerDim;
+class LayerBuffer;
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+class Client : public BnSurfaceComposerClient
+{
+public:
+        Client(const sp<SurfaceFlinger>& flinger);
+        ~Client();
+
+    status_t initCheck() const;
+
+    // protected by SurfaceFlinger::mStateLock
+    ssize_t attachLayer(const sp<LayerBaseClient>& layer);
+    void detachLayer(const LayerBaseClient* layer);
+    sp<LayerBaseClient> getLayerUser(int32_t i) const;
+
+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);
+
+    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;
+};
+
+// ---------------------------------------------------------------------------
+
+class GraphicPlane
+{
+public:
+    static status_t orientationToTransfrom(int orientation, int w, int h,
+            Transform* tr);
+
+                                GraphicPlane();
+                                ~GraphicPlane();
+
+        bool                    initialized() const;
+
+        void                    setDisplayHardware(DisplayHardware *);
+        status_t                setOrientation(int orientation);
+        int                     getOrientation() const { return mOrientation; }
+        int                     getWidth() const;
+        int                     getHeight() const;
+
+        const DisplayHardware&  displayHardware() const;
+        DisplayHardware&        editDisplayHardware();
+        const Transform&        transform() const;
+        EGLDisplay              getEGLDisplay() const;
+        
+private:
+                                GraphicPlane(const GraphicPlane&);
+        GraphicPlane            operator = (const GraphicPlane&);
+
+        DisplayHardware*        mHw;
+        Transform               mGlobalTransform;
+        Transform               mDisplayTransform;
+        int                     mOrientation;
+        float                   mDisplayWidth;
+        float                   mDisplayHeight;
+        int                     mWidth;
+        int                     mHeight;
+};
+
+// ---------------------------------------------------------------------------
+
+enum {
+    eTransactionNeeded      = 0x01,
+    eTraversalNeeded        = 0x02
+};
+
+class SurfaceFlinger :
+        public BinderService<SurfaceFlinger>,
+        public BnSurfaceComposer,
+        protected Thread
+{
+public:
+    static char const* getServiceName() { return "SurfaceFlinger"; }
+
+                    SurfaceFlinger();
+    virtual         ~SurfaceFlinger();
+            void    init();
+
+    virtual status_t onTransact(
+        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
+
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
+    // ISurfaceComposer interface
+    virtual sp<ISurfaceComposerClient>  createConnection();
+    virtual sp<ISurfaceComposerClient>  createClientConnection();
+    virtual sp<IMemoryHeap>             getCblk() const;
+    virtual void                        bootFinished();
+    virtual void                        openGlobalTransaction();
+    virtual void                        closeGlobalTransaction();
+    virtual status_t                    freezeDisplay(DisplayID dpy, uint32_t flags);
+    virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
+    virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
+    virtual void                        signal() const;
+    virtual status_t                    captureScreen(DisplayID dpy,
+                                                      sp<IMemoryHeap>* heap,
+                                                      uint32_t* width,
+                                                      uint32_t* height,
+                                                      PixelFormat* format,
+                                                      uint32_t reqWidth,
+                                                      uint32_t reqHeight);
+    virtual status_t                    turnElectronBeamOff(int32_t mode);
+    virtual status_t                    turnElectronBeamOn(int32_t mode);
+
+            void                        screenReleased(DisplayID dpy);
+            void                        screenAcquired(DisplayID dpy);
+
+            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 Client;
+    friend class LayerBase;
+    friend class LayerBuffer;
+    friend class LayerBaseClient;
+    friend class LayerBaseClient::Surface;
+    friend class Layer;
+    friend class LayerBlur;
+    friend class LayerDim;
+
+    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<Layer> createNormalSurface(
+            const sp<Client>& client, DisplayID display,
+            uint32_t w, uint32_t h, uint32_t flags,
+            PixelFormat& format);
+
+    sp<LayerBlur> createBlurSurface(
+            const sp<Client>& client, DisplayID display,
+            uint32_t w, uint32_t h, uint32_t flags);
+
+    sp<LayerDim> createDimSurface(
+            const sp<Client>& client, DisplayID display,
+            uint32_t w, uint32_t h, uint32_t flags);
+
+    sp<LayerBuffer> createPushBuffersSurface(
+            const sp<Client>& client, DisplayID display,
+            uint32_t w, uint32_t h, uint32_t flags);
+
+    status_t removeSurface(const sp<Client>& client, SurfaceID sid);
+    status_t destroySurface(const sp<LayerBaseClient>& layer);
+    status_t setClientState(const sp<Client>& client,
+            int32_t count, const layer_state_t* states);
+
+    class LayerVector : public SortedVector< sp<LayerBase> > {
+    public:
+        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 {
+        State() {
+            orientation = ISurfaceComposer::eOrientationDefault;
+            freezeDisplay = 0;
+        }
+        LayerVector     layersSortedByZ;
+        uint8_t         orientation;
+        uint8_t         orientationType;
+        uint8_t         freezeDisplay;
+    };
+
+    virtual bool        threadLoop();
+    virtual status_t    readyToRun();
+    virtual void        onFirstRef();
+
+public:     // hack to work around gcc 4.0.3 bug
+    const GraphicPlane&     graphicPlane(int dpy) const;
+          GraphicPlane&     graphicPlane(int dpy);
+private:
+
+            void        waitForEvent();
+public:     // hack to work around gcc 4.0.3 bug
+            void        signalEvent();
+private:
+            void        handleConsoleEvents();
+            void        handleTransaction(uint32_t transactionFlags);
+            void        handleTransactionLocked(
+                            uint32_t transactionFlags, 
+                            Vector< sp<LayerBase> >& ditchedLayers);
+
+            void        computeVisibleRegions(
+                            LayerVector& currentLayers,
+                            Region& dirtyRegion,
+                            Region& wormholeRegion);
+
+            void        handlePageFlip();
+            bool        lockPageFlip(const LayerVector& currentLayers);
+            void        unlockPageFlip(const LayerVector& currentLayers);
+            void        handleRepaint();
+            void        postFramebuffer();
+            void        composeSurfaces(const Region& dirty);
+            void        unlockClients();
+
+
+            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);
+
+            uint32_t    getTransactionFlags(uint32_t flags);
+            uint32_t    setTransactionFlags(uint32_t flags);
+            void        commitTransaction();
+
+
+            status_t captureScreenImplLocked(DisplayID dpy,
+                    sp<IMemoryHeap>* heap,
+                    uint32_t* width, uint32_t* height, PixelFormat* format,
+                    uint32_t reqWidth = 0, uint32_t reqHeight = 0);
+
+            status_t turnElectronBeamOffImplLocked(int32_t mode);
+            status_t turnElectronBeamOnImplLocked(int32_t mode);
+            status_t electronBeamOffAnimationImplLocked();
+            status_t electronBeamOnAnimationImplLocked();
+            status_t renderScreenToTextureLocked(DisplayID dpy,
+                    GLuint* textureName, GLfloat* uOut, GLfloat* vOut);
+
+            friend class FreezeLock;
+            sp<FreezeLock> getFreezeLock() const;
+            inline void incFreezeCount() {
+                if (mFreezeCount == 0)
+                    mFreezeDisplayTime = 0;
+                mFreezeCount++;
+            }
+            inline void decFreezeCount() { if (mFreezeCount > 0) mFreezeCount--; }
+            inline bool hasFreezeRequest() const { return mFreezeDisplay; }
+            inline bool isFrozen() const { 
+                return (mFreezeDisplay || mFreezeCount>0) && mBootFinished;
+            }
+
+            
+            void        debugFlashRegions();
+            void        debugShowFPS() const;
+            void        drawWormhole() const;
+           
+
+    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;
+                State                   mDrawingState;
+    volatile    int32_t                 mTransactionFlags;
+    volatile    int32_t                 mTransactionCount;
+                Condition               mTransactionCV;
+                bool                    mResizeTransationPending;
+
+                // protected by mStateLock (but we could use another lock)
+                GraphicPlane                mGraphicPlanes[1];
+                bool                        mLayersRemoved;
+                DefaultKeyedVector< wp<IBinder>, wp<Layer> > mLayerMap;
+
+                // constant members (no synchronization needed for access)
+                sp<IMemoryHeap>             mServerHeap;
+                surface_flinger_cblk_t*     mServerCblk;
+                GLuint                      mWormholeTexName;
+                nsecs_t                     mBootTime;
+                Permission                  mHardwareTest;
+                Permission                  mAccessSurfaceFlinger;
+                Permission                  mReadFramebuffer;
+                Permission                  mDump;
+                
+                // Can only accessed from the main thread, these members
+                // don't need synchronization
+                Region                      mDirtyRegion;
+                Region                      mDirtyRegionRemovedLayer;
+                Region                      mInvalidRegion;
+                Region                      mWormholeRegion;
+                bool                        mVisibleRegionsDirty;
+                bool                        mDeferReleaseConsole;
+                bool                        mFreezeDisplay;
+                int32_t                     mElectronBeamAnimationMode;
+                int32_t                     mFreezeCount;
+                nsecs_t                     mFreezeDisplayTime;
+                Vector< sp<LayerBase> >     mVisibleLayersSortedByZ;
+
+
+                // don't use a lock for these, we don't care
+                int                         mDebugRegion;
+                int                         mDebugBackground;
+                volatile nsecs_t            mDebugInSwapBuffers;
+                nsecs_t                     mLastSwapBufferTime;
+                volatile nsecs_t            mDebugInTransaction;
+                nsecs_t                     mLastTransactionTime;
+                bool                        mBootFinished;
+
+                // these are thread safe
+    mutable     Barrier                     mReadyToRunBarrier;
+
+                // atomic variables
+                enum {
+                    eConsoleReleased = 1,
+                    eConsoleAcquired = 2
+                };
+   volatile     int32_t                     mConsoleSignals;
+
+   // only written in the main thread, only read in other threads
+   volatile     int32_t                     mSecureFrameBuffer;
+};
+
+// ---------------------------------------------------------------------------
+
+class FreezeLock : public LightRefBase<FreezeLock> {
+    SurfaceFlinger* mFlinger;
+public:
+    FreezeLock(SurfaceFlinger* flinger)
+        : mFlinger(flinger) {
+        mFlinger->incFreezeCount();
+    }
+    ~FreezeLock() {
+        mFlinger->decFreezeCount();
+    }
+};
+
+// ---------------------------------------------------------------------------
+}; // 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..c9a15f5
--- /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_EGL_image_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_EGL_image_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_EGL_image_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_EGL_image_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/Transform.cpp b/services/surfaceflinger/Transform.cpp
new file mode 100644
index 0000000..0467a14
--- /dev/null
+++ b/services/surfaceflinger/Transform.cpp
@@ -0,0 +1,387 @@
+/*
+ * 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 <math.h>
+
+#include <cutils/compiler.h>
+#include <utils/String8.h>
+#include <ui/Region.h>
+
+#include "Transform.h"
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+static inline T min(T a, T b) {
+    return a<b ? a : b;
+}
+template <typename T>
+static inline T min(T a, T b, T c) {
+    return min(a, min(b, c));
+}
+template <typename T>
+static inline T min(T a, T b, T c, T d) {
+    return min(a, b, min(c, d));
+}
+
+template <typename T>
+static inline T max(T a, T b) {
+    return a>b ? a : b;
+}
+template <typename T>
+static inline T max(T a, T b, T c) {
+    return max(a, max(b, c));
+}
+template <typename T>
+static inline T max(T a, T b, T c, T d) {
+    return max(a, b, max(c, d));
+}
+
+template <typename T>
+static inline
+void swap(T& a, T& b) {
+    T t(a);
+    a = b;
+    b = t;
+}
+
+// ---------------------------------------------------------------------------
+
+Transform::Transform() {
+    reset();
+}
+
+Transform::Transform(const Transform&  other)
+    : mMatrix(other.mMatrix), mType(other.mType) {
+}
+
+Transform::Transform(uint32_t orientation) {
+    set(orientation, 0, 0);
+}
+
+Transform::~Transform() {
+}
+
+static const float EPSILON = 0.0f;
+
+bool Transform::isZero(float f) {
+    return fabs(f) <= EPSILON;
+}
+
+bool Transform::absIsOne(float f) {
+    return isZero(fabs(f) - 1.0f);
+}
+
+Transform Transform::operator * (const Transform& rhs) const
+{
+    if (CC_LIKELY(mType == IDENTITY))
+        return rhs;
+
+    Transform r(*this);
+    if (rhs.mType == IDENTITY)
+        return r;
+
+    // TODO: we could use mType to optimize the matrix multiply
+    const mat33& A(mMatrix);
+    const mat33& B(rhs.mMatrix);
+          mat33& D(r.mMatrix);
+    for (int i=0 ; i<3 ; i++) {
+        const float v0 = A[0][i];
+        const float v1 = A[1][i];
+        const float v2 = A[2][i];
+        D[0][i] = v0*B[0][0] + v1*B[0][1] + v2*B[0][2];
+        D[1][i] = v0*B[1][0] + v1*B[1][1] + v2*B[1][2];
+        D[2][i] = v0*B[2][0] + v1*B[2][1] + v2*B[2][2];
+    }
+    r.mType |= rhs.mType;
+
+    // TODO: we could recompute this value from r and rhs
+    r.mType &= 0xFF;
+    r.mType |= UNKNOWN_TYPE;
+    return r;
+}
+
+float const* Transform::operator [] (int i) const {
+    return mMatrix[i].v;
+}
+
+bool Transform::transformed() const {
+    return type() > TRANSLATE;
+}
+
+int Transform::tx() const {
+    return floorf(mMatrix[2][0] + 0.5f);
+}
+
+int Transform::ty() const {
+    return floorf(mMatrix[2][1] + 0.5f);
+}
+
+void Transform::reset() {
+    mType = IDENTITY;
+    for(int i=0 ; i<3 ; i++) {
+        vec3& v(mMatrix[i]);
+        for (int j=0 ; j<3 ; j++)
+            v[j] = ((i==j) ? 1.0f : 0.0f);
+    }
+}
+
+void Transform::set(float tx, float ty)
+{
+    mMatrix[2][0] = tx;
+    mMatrix[2][1] = ty;
+    mMatrix[2][2] = 1.0f;
+
+    if (isZero(tx) && isZero(ty)) {
+        mType &= ~TRANSLATE;
+    } else {
+        mType |= TRANSLATE;
+    }
+}
+
+void Transform::set(float a, float b, float c, float d)
+{
+    mat33& M(mMatrix);
+    M[0][0] = a;    M[1][0] = b;
+    M[0][1] = c;    M[1][1] = d;
+    M[0][2] = 0;    M[1][2] = 0;
+    mType = UNKNOWN_TYPE;
+}
+
+status_t Transform::set(uint32_t flags, float w, float h)
+{
+    if (flags & ROT_INVALID) {
+        // that's not allowed!
+        reset();
+        return BAD_VALUE;
+    }
+
+    Transform H, V, R;
+    if (flags & ROT_90) {
+        // w & h are inverted when rotating by 90 degrees
+        swap(w, h);
+    }
+
+    if (flags & FLIP_H) {
+        H.mType = (FLIP_H << 8) | SCALE;
+        H.mType |= isZero(w) ? IDENTITY : TRANSLATE;
+        mat33& M(H.mMatrix);
+        M[0][0] = -1;
+        M[2][0] = w;
+    }
+
+    if (flags & FLIP_V) {
+        V.mType = (FLIP_V << 8) | SCALE;
+        V.mType |= isZero(h) ? IDENTITY : TRANSLATE;
+        mat33& M(V.mMatrix);
+        M[1][1] = -1;
+        M[2][1] = h;
+    }
+
+    if (flags & ROT_90) {
+        const float original_w = h;
+        R.mType = (ROT_90 << 8) | ROTATE;
+        R.mType |= isZero(original_w) ? IDENTITY : TRANSLATE;
+        mat33& M(R.mMatrix);
+        M[0][0] = 0;    M[1][0] =-1;    M[2][0] = original_w;
+        M[0][1] = 1;    M[1][1] = 0;
+    }
+
+    *this = (R*(H*V));
+    return NO_ERROR;
+}
+
+Transform::vec2 Transform::transform(const vec2& v) const {
+    vec2 r;
+    const mat33& M(mMatrix);
+    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0];
+    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1];
+    return r;
+}
+
+Transform::vec3 Transform::transform(const vec3& v) const {
+    vec3 r;
+    const mat33& M(mMatrix);
+    r[0] = M[0][0]*v[0] + M[1][0]*v[1] + M[2][0]*v[2];
+    r[1] = M[0][1]*v[0] + M[1][1]*v[1] + M[2][1]*v[2];
+    r[2] = M[0][2]*v[0] + M[1][2]*v[1] + M[2][2]*v[2];
+    return r;
+}
+
+void Transform::transform(float* point, int x, int y) const
+{
+    const mat33& M(mMatrix);
+    vec2 v(x, y);
+    v = transform(v);
+    point[0] = v[0];
+    point[1] = v[1];
+}
+
+Rect Transform::makeBounds(int w, int h) const
+{
+    return transform( Rect(w, h) );
+}
+
+Rect Transform::transform(const Rect& bounds) const
+{
+    Rect r;
+    vec2 lt( bounds.left,  bounds.top    );
+    vec2 rt( bounds.right, bounds.top    );
+    vec2 lb( bounds.left,  bounds.bottom );
+    vec2 rb( bounds.right, bounds.bottom );
+
+    lt = transform(lt);
+    rt = transform(rt);
+    lb = transform(lb);
+    rb = transform(rb);
+
+    r.left   = floorf(min(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
+    r.top    = floorf(min(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+    r.right  = floorf(max(lt[0], rt[0], lb[0], rb[0]) + 0.5f);
+    r.bottom = floorf(max(lt[1], rt[1], lb[1], rb[1]) + 0.5f);
+
+    return r;
+}
+
+Region Transform::transform(const Region& reg) const
+{
+    Region out;
+    if (CC_UNLIKELY(transformed())) {
+        if (CC_LIKELY(preserveRects())) {
+            Region::const_iterator it = reg.begin();
+            Region::const_iterator const end = reg.end();
+            while (it != end) {
+                out.orSelf(transform(*it++));
+            }
+        } else {
+            out.set(transform(reg.bounds()));
+        }
+    } else {
+        out = reg.translate(tx(), ty());
+    }
+    return out;
+}
+
+uint32_t Transform::type() const
+{
+    if (mType & UNKNOWN_TYPE) {
+        // recompute what this transform is
+
+        const mat33& M(mMatrix);
+        const float a = M[0][0];
+        const float b = M[1][0];
+        const float c = M[0][1];
+        const float d = M[1][1];
+        const float x = M[2][0];
+        const float y = M[2][1];
+
+        bool scale = false;
+        uint32_t flags = ROT_0;
+        if (isZero(b) && isZero(c)) {
+            if (a<0)    flags |= FLIP_H;
+            if (d<0)    flags |= FLIP_V;
+            if (!absIsOne(a) || !absIsOne(d)) {
+                scale = true;
+            }
+        } else if (isZero(a) && isZero(d)) {
+            flags |= ROT_90;
+            if (b>0)    flags |= FLIP_V;
+            if (c<0)    flags |= FLIP_H;
+            if (!absIsOne(b) || !absIsOne(c)) {
+                scale = true;
+            }
+        } else {
+            flags = ROT_INVALID;
+        }
+
+        mType = flags << 8;
+        if (flags & ROT_INVALID) {
+            mType |= UNKNOWN;
+        } else {
+            if ((flags & ROT_90) || ((flags & ROT_180) == ROT_180))
+                mType |= ROTATE;
+            if (flags & FLIP_H)
+                mType ^= SCALE;
+            if (flags & FLIP_V)
+                mType ^= SCALE;
+            if (scale)
+                mType |= SCALE;
+        }
+
+        if (!isZero(x) || !isZero(y))
+            mType |= TRANSLATE;
+    }
+    return mType;
+}
+
+uint32_t Transform::getType() const {
+    return type() & 0xFF;
+}
+
+uint32_t Transform::getOrientation() const
+{
+    return (type() >> 8) & 0xFF;
+}
+
+bool Transform::preserveRects() const
+{
+    return (type() & ROT_INVALID) ? false : true;
+}
+
+void Transform::dump(const char* name) const
+{
+    type(); // updates the type
+
+    String8 flags, type;
+    const mat33& m(mMatrix);
+    uint32_t orient = mType >> 8;
+
+    if (orient&ROT_INVALID) {
+        flags.append("ROT_INVALID ");
+    } else {
+        if (orient&ROT_90) {
+            flags.append("ROT_90 ");
+        } else {
+            flags.append("ROT_0 ");
+        }
+        if (orient&FLIP_V)
+            flags.append("FLIP_V ");
+        if (orient&FLIP_H)
+            flags.append("FLIP_H ");
+    }
+
+    if (!(mType&(SCALE|ROTATE|TRANSLATE)))
+        type.append("IDENTITY ");
+    if (mType&SCALE)
+        type.append("SCALE ");
+    if (mType&ROTATE)
+        type.append("ROTATE ");
+    if (mType&TRANSLATE)
+        type.append("TRANSLATE ");
+
+    LOGD("%s 0x%08x (%s, %s)", name, mType, flags.string(), type.string());
+    LOGD("%.4f  %.4f  %.4f", m[0][0], m[1][0], m[2][0]);
+    LOGD("%.4f  %.4f  %.4f", m[0][1], m[1][1], m[2][1]);
+    LOGD("%.4f  %.4f  %.4f", m[0][2], m[1][2], m[2][2]);
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
new file mode 100644
index 0000000..8fa5b86
--- /dev/null
+++ b/services/surfaceflinger/Transform.h
@@ -0,0 +1,127 @@
+/*
+ * 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_TRANSFORM_H
+#define ANDROID_TRANSFORM_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <hardware/hardware.h>
+
+namespace android {
+
+class Region;
+
+// ---------------------------------------------------------------------------
+
+class Transform
+{
+public:
+                    Transform();
+                    Transform(const Transform&  other);
+           explicit Transform(uint32_t orientation);
+                    ~Transform();
+
+            enum orientation_flags {
+                ROT_0   = 0x00000000,
+                FLIP_H  = HAL_TRANSFORM_FLIP_H,
+                FLIP_V  = HAL_TRANSFORM_FLIP_V,
+                ROT_90  = HAL_TRANSFORM_ROT_90,
+                ROT_180 = FLIP_H|FLIP_V,
+                ROT_270 = ROT_180|ROT_90,
+                ROT_INVALID = 0x80
+            };
+
+            enum type_mask {
+                IDENTITY            = 0,
+                TRANSLATE           = 0x1,
+                ROTATE              = 0x2,
+                SCALE               = 0x4,
+                UNKNOWN             = 0x8
+            };
+
+            // query the transform
+            bool        transformed() const;
+            bool        preserveRects() const;
+            uint32_t    getType() const;
+            uint32_t    getOrientation() const;
+
+            float const* operator [] (int i) const;  // returns column i
+            int     tx() const;
+            int     ty() const;
+
+            // modify the transform
+            void        reset();
+            void        set(float tx, float ty);
+            void        set(float a, float b, float c, float d);
+            status_t    set(uint32_t flags, float w, float h);
+
+            // transform data
+            Rect    makeBounds(int w, int h) const;
+            void    transform(float* point, int x, int y) const;
+            Region  transform(const Region& reg) const;
+            Transform operator * (const Transform& rhs) const;
+
+            // for debugging
+            void dump(const char* name) const;
+
+private:
+    struct vec3 {
+        float v[3];
+        inline vec3() { }
+        inline vec3(float a, float b, float c) {
+            v[0] = a; v[1] = b; v[2] = c;
+        }
+        inline float operator [] (int i) const { return v[i]; }
+        inline float& operator [] (int i) { return v[i]; }
+    };
+    struct vec2 {
+        float v[2];
+        inline vec2() { }
+        inline vec2(float a, float b) {
+            v[0] = a; v[1] = b;
+        }
+        inline float operator [] (int i) const { return v[i]; }
+        inline float& operator [] (int i) { return v[i]; }
+    };
+    struct mat33 {
+        vec3 v[3];
+        inline const vec3& operator [] (int i) const { return v[i]; }
+        inline vec3& operator [] (int i) { return v[i]; }
+    };
+
+    enum { UNKNOWN_TYPE = 0x80000000 };
+
+    // assumes the last row is < 0 , 0 , 1 >
+    vec2 transform(const vec2& v) const;
+    vec3 transform(const vec3& v) const;
+    Rect transform(const Rect& bounds) const;
+    uint32_t type() const;
+    static bool absIsOne(float f);
+    static bool isZero(float f);
+
+    mat33               mMatrix;
+    mutable uint32_t    mType;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif /* ANDROID_TRANSFORM_H */
diff --git a/libs/surfaceflinger/clz.cpp b/services/surfaceflinger/clz.cpp
similarity index 100%
rename from libs/surfaceflinger/clz.cpp
rename to services/surfaceflinger/clz.cpp
diff --git a/libs/surfaceflinger/clz.h b/services/surfaceflinger/clz.h
similarity index 100%
rename from libs/surfaceflinger/clz.h
rename to services/surfaceflinger/clz.h
diff --git a/libs/surfaceflinger/tests/Android.mk b/services/surfaceflinger/tests/Android.mk
similarity index 100%
copy from libs/surfaceflinger/tests/Android.mk
copy to services/surfaceflinger/tests/Android.mk
diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/services/surfaceflinger/tests/overlays/Android.mk
similarity index 100%
rename from libs/surfaceflinger/tests/overlays/Android.mk
rename to services/surfaceflinger/tests/overlays/Android.mk
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/services/surfaceflinger/tests/overlays/overlays.cpp
similarity index 100%
rename from libs/surfaceflinger/tests/overlays/overlays.cpp
rename to services/surfaceflinger/tests/overlays/overlays.cpp
diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/services/surfaceflinger/tests/resize/Android.mk
similarity index 100%
rename from libs/surfaceflinger/tests/resize/Android.mk
rename to services/surfaceflinger/tests/resize/Android.mk
diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
similarity index 100%
rename from libs/surfaceflinger/tests/resize/resize.cpp
rename to services/surfaceflinger/tests/resize/resize.cpp
diff --git a/services/surfaceflinger/tests/screencap/Android.mk b/services/surfaceflinger/tests/screencap/Android.mk
new file mode 100644
index 0000000..1cfb471
--- /dev/null
+++ b/services/surfaceflinger/tests/screencap/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	screencap.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libskia \
+    libui \
+    libsurfaceflinger_client
+
+LOCAL_MODULE:= test-screencap
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES += \
+	external/skia/include/core \
+	external/skia/include/effects \
+	external/skia/include/images \
+	external/skia/src/ports \
+	external/skia/include/utils
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/screencap/screencap.cpp b/services/surfaceflinger/tests/screencap/screencap.cpp
new file mode 100644
index 0000000..6cf1504
--- /dev/null
+++ b/services/surfaceflinger/tests/screencap/screencap.cpp
@@ -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.
+ */
+
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+#include <binder/IMemory.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+
+#include <SkImageEncoder.h>
+#include <SkBitmap.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+    if (argc != 2) {
+        printf("usage: %s path\n", argv[0]);
+        exit(0);
+    }
+
+    const String16 name("SurfaceFlinger");
+    sp<ISurfaceComposer> composer;
+    getService(name, &composer);
+
+    sp<IMemoryHeap> heap;
+    uint32_t w, h;
+    PixelFormat f;
+    status_t err = composer->captureScreen(0, &heap, &w, &h, &f, 0, 0);
+    if (err != NO_ERROR) {
+        fprintf(stderr, "screen capture failed: %s\n", strerror(-err));
+        exit(0);
+    }
+
+    printf("screen capture success: w=%u, h=%u, pixels=%p\n",
+            w, h, heap->getBase());
+
+    printf("saving file as PNG in %s ...\n", argv[1]);
+
+    SkBitmap b;
+    b.setConfig(SkBitmap::kARGB_8888_Config, w, h);
+    b.setPixels(heap->getBase());
+    SkImageEncoder::EncodeFile(argv[1], b,
+            SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality);
+
+    return 0;
+}
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/services/surfaceflinger/tests/transform/Android.mk b/services/surfaceflinger/tests/transform/Android.mk
new file mode 100644
index 0000000..6219dae
--- /dev/null
+++ b/services/surfaceflinger/tests/transform/Android.mk
@@ -0,0 +1,19 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	TransformTest.cpp \
+	../../Transform.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libui \
+
+LOCAL_MODULE:= test-transform
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_C_INCLUDES += ../..
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/transform/TransformTest.cpp b/services/surfaceflinger/tests/transform/TransformTest.cpp
new file mode 100644
index 0000000..e112c4e
--- /dev/null
+++ b/services/surfaceflinger/tests/transform/TransformTest.cpp
@@ -0,0 +1,45 @@
+/*
+ * 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 <utils/Errors.h>
+#include "../../Transform.h"
+
+using namespace android;
+
+int main(int argc, char **argv)
+{
+    Transform tr90(Transform::ROT_90);
+    Transform trFH(Transform::FLIP_H);
+    Transform trFV(Transform::FLIP_V);
+
+    Transform tr90FH(Transform::ROT_90 | Transform::FLIP_H);
+    Transform tr90FV(Transform::ROT_90 | Transform::FLIP_V);
+
+    tr90.dump("tr90");
+    trFH.dump("trFH");
+    trFV.dump("trFV");
+
+    tr90FH.dump("tr90FH");
+    tr90FV.dump("tr90FV");
+
+    (trFH*tr90).dump("trFH*tr90");
+    (trFV*tr90).dump("trFV*tr90");
+
+    (tr90*trFH).dump("tr90*trFH");
+    (tr90*trFV).dump("tr90*trFV");
+
+    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;
     }
 
     /**
