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/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..d689667 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -43,24 +43,9 @@
  * unless they are in use by the server, which is only the case for the last 
  * dequeue-able buffer. When these various conditions are not met, the caller
  * waits until the condition is met.
- *
- * 
- * CAVEATS:
- * 
- * In the current implementation there are several limitations:
- * - buffers must be locked in the same order they've been dequeued
- * - buffers must be enqueued in the same order they've been locked
- * - dequeue() is not reentrant
- * - no error checks are done on the condition above
  * 
  */
 
-// When changing these values, the COMPILE_TIME_ASSERT at the end of this
-// file need to be updated.
-const unsigned int NUM_LAYERS_MAX  = 31;
-const unsigned int NUM_BUFFER_MAX  = 4;
-const unsigned int NUM_DISPLAY_MAX = 4;
-
 // ----------------------------------------------------------------------------
 
 class Region;
@@ -69,7 +54,6 @@
 
 // ----------------------------------------------------------------------------
 
-// should be 128 bytes (32 longs)
 class SharedBufferStack
 {
     friend class SharedClient;
@@ -78,22 +62,44 @@
     friend class SharedBufferServer;
 
 public:
-    struct FlatRegion { // 12 bytes
-        static const unsigned int NUM_RECT_MAX = 1;
-        uint32_t    count;
-        uint16_t    rects[4*NUM_RECT_MAX];
-    };
-    
+    // When changing these values, the COMPILE_TIME_ASSERT at the end of this
+    // file need to be updated.
+    static const unsigned int NUM_LAYERS_MAX  = 31;
+    static const unsigned int NUM_BUFFER_MAX  = 16;
+    static const unsigned int NUM_BUFFER_MIN  = 2;
+    static const unsigned int NUM_DISPLAY_MAX = 4;
+
     struct Statistics { // 4 longs
         typedef int32_t usecs_t;
         usecs_t  totalTime;
         usecs_t  reserved[3];
     };
+
+    struct SmallRect {
+        uint16_t l, t, r, b;
+    };
+
+    struct FlatRegion { // 52 bytes = 4 * (1 + 2*N)
+        static const unsigned int NUM_RECT_MAX = 5;
+        uint32_t    count;
+        SmallRect   rects[NUM_RECT_MAX];
+    };
+    
+    struct BufferData {
+        FlatRegion dirtyRegion;
+        SmallRect  crop;
+        uint8_t transform;
+        uint8_t reserved[3];
+    };
     
     SharedBufferStack();
     void init(int32_t identity);
     status_t setDirtyRegion(int buffer, const Region& reg);
+    status_t setCrop(int buffer, const Rect& reg);
+    status_t setTransform(int buffer, uint8_t transform);
     Region getDirtyRegion(int buffer) const;
+    Rect getCrop(int buffer) const;
+    uint32_t getTransform(int buffer) const;
 
     // these attributes are part of the conditions/updates
     volatile int32_t head;      // server's current front buffer
@@ -104,24 +110,25 @@
 
     // not part of the conditions
     volatile int32_t reallocMask;
+    volatile int8_t index[NUM_BUFFER_MAX];
 
     int32_t     identity;       // surface's identity (const)
-    int32_t     reserved32[9];
+    int32_t     token;          // surface's token (for debugging)
+    int32_t     reserved32[1];
     Statistics  stats;
-    FlatRegion  dirtyRegion[NUM_BUFFER_MAX];    // 12*4=48 bytes
+    int32_t     reserved;
+    BufferData  buffers[NUM_BUFFER_MAX];     // 1024 bytes
 };
 
 // ----------------------------------------------------------------------------
 
-// 4 KB max
+// 32 KB max
 class SharedClient
 {
 public:
     SharedClient();
     ~SharedClient();
-
     status_t validate(size_t token) const;
-    uint32_t getIdentity(size_t token) const;
 
 private:
     friend class SharedBufferBase;
@@ -131,7 +138,7 @@
     // FIXME: this should be replaced by a lock-less primitive
     Mutex lock;
     Condition cv;
-    SharedBufferStack surfaces[ NUM_LAYERS_MAX ];
+    SharedBufferStack surfaces[ SharedBufferStack::NUM_LAYERS_MAX ];
 };
 
 // ============================================================================
@@ -139,18 +146,16 @@
 class SharedBufferBase
 {
 public:
-    SharedBufferBase(SharedClient* sharedClient, int surface, int num,
+    SharedBufferBase(SharedClient* sharedClient, int surface,
             int32_t identity);
     ~SharedBufferBase();
-    uint32_t getIdentity();
     status_t getStatus() const;
-    size_t getFrontBuffer() const;
+    int32_t getIdentity() const;
     String8 dump(char const* prefix) const;
 
 protected:
     SharedClient* const mSharedClient;
     SharedBufferStack* const mSharedStack;
-    const int mNumBuffers;
     const int mIdentity;
 
     friend struct Update;
@@ -160,61 +165,22 @@
         SharedBufferStack& stack;
         inline ConditionBase(SharedBufferBase* sbc) 
             : stack(*sbc->mSharedStack) { }
+        virtual ~ConditionBase() { };
+        virtual bool operator()() const = 0;
+        virtual const char* name() const = 0;
     };
+    status_t waitForCondition(const ConditionBase& condition);
 
     struct UpdateBase {
         SharedBufferStack& stack;
         inline UpdateBase(SharedBufferBase* sbb) 
             : stack(*sbb->mSharedStack) { }
     };
-
-    template <typename T>
-    status_t waitForCondition(T condition);
-
     template <typename T>
     status_t updateCondition(T update);
 };
 
 template <typename T>
-status_t SharedBufferBase::waitForCondition(T condition) 
-{
-    const SharedBufferStack& stack( *mSharedStack );
-    SharedClient& client( *mSharedClient );
-    const nsecs_t TIMEOUT = s2ns(1);
-    Mutex::Autolock _l(client.lock);
-    while ((condition()==false) &&
-            (stack.identity == mIdentity) &&
-            (stack.status == NO_ERROR))
-    {
-        status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
-        
-        // handle errors and timeouts
-        if (CC_UNLIKELY(err != NO_ERROR)) {
-            if (err == TIMED_OUT) {
-                if (condition()) {
-                    LOGE("waitForCondition(%s) timed out (identity=%d), "
-                        "but condition is true! We recovered but it "
-                        "shouldn't happen." , T::name(),
-                        stack.identity);
-                    break;
-                } else {
-                    LOGW("waitForCondition(%s) timed out "
-                        "(identity=%d, status=%d). "
-                        "CPU may be pegged. trying again.", T::name(),
-                        stack.identity, stack.status);
-                }
-            } else {
-                LOGE("waitForCondition(%s) error (%s) ",
-                        T::name(), strerror(-err));
-                return err;
-            }
-        }
-    }
-    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
-}
-
-
-template <typename T>
 status_t SharedBufferBase::updateCondition(T update) {
     SharedClient& client( *mSharedClient );
     Mutex::Autolock _l(client.lock);
@@ -238,19 +204,32 @@
     status_t queue(int buf);
     bool needNewBuffer(int buffer) const;
     status_t setDirtyRegion(int buffer, const Region& reg);
-    
+    status_t setCrop(int buffer, const Rect& reg);
+    status_t setTransform(int buffer, uint32_t transform);
+
+    class SetBufferCountCallback {
+        friend class SharedBufferClient;
+        virtual status_t operator()(int bufferCount) const = 0;
+    protected:
+        virtual ~SetBufferCountCallback() { }
+    };
+    status_t setBufferCount(int bufferCount, const SetBufferCountCallback& ipc);
+
 private:
     friend struct Condition;
     friend struct DequeueCondition;
     friend struct LockCondition;
-    
-    int32_t computeTail() const;
 
     struct QueueUpdate : public UpdateBase {
         inline QueueUpdate(SharedBufferBase* sbb);
         inline ssize_t operator()();
     };
 
+    struct DequeueUpdate : public UpdateBase {
+        inline DequeueUpdate(SharedBufferBase* sbb);
+        inline ssize_t operator()();
+    };
+
     struct UndoDequeueUpdate : public UpdateBase {
         inline UndoDequeueUpdate(SharedBufferBase* sbb);
         inline ssize_t operator()();
@@ -260,25 +239,34 @@
 
     struct DequeueCondition : public ConditionBase {
         inline DequeueCondition(SharedBufferClient* sbc);
-        inline bool operator()();
-        static inline const char* name() { return "DequeueCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "DequeueCondition"; }
     };
 
     struct LockCondition : public ConditionBase {
         int buf;
         inline LockCondition(SharedBufferClient* sbc, int buf);
-        inline bool operator()();
-        static inline const char* name() { return "LockCondition"; }
+        inline bool operator()() const;
+        inline const char* name() const { return "LockCondition"; }
     };
 
+    int32_t computeTail() const;
+
+    mutable RWLock mLock;
+    int mNumBuffers;
+
     int32_t tail;
+    int32_t undoDequeueTail;
+    int32_t queued_head;
     // statistics...
-    nsecs_t mDequeueTime[NUM_BUFFER_MAX];
+    nsecs_t mDequeueTime[SharedBufferStack::NUM_BUFFER_MAX];
 };
 
 // ----------------------------------------------------------------------------
 
-class SharedBufferServer : public SharedBufferBase
+class SharedBufferServer
+    : public SharedBufferBase,
+      public LightRefBase<SharedBufferServer>
 {
 public:
     SharedBufferServer(SharedClient* sharedClient, int surface, int num,
@@ -287,16 +275,75 @@
     ssize_t retireAndLock();
     status_t unlock(int buffer);
     void setStatus(status_t status);
-    status_t reallocate();
-    status_t assertReallocate(int buffer);
+    status_t reallocateAll();
+    status_t reallocateAllExcept(int buffer);
     int32_t getQueuedCount() const;
-    
     Region getDirtyRegion(int buffer) const;
+    Rect getCrop(int buffer) const;
+    uint32_t getTransform(int buffer) const;
+
+    status_t resize(int newNumBuffers);
 
     SharedBufferStack::Statistics getStats() const;
     
 
 private:
+    friend class LightRefBase<SharedBufferServer>;
+    ~SharedBufferServer();
+
+    /*
+     * BufferList is basically a fixed-capacity sorted-vector of
+     * unsigned 5-bits ints using a 32-bits int as storage.
+     * it has efficient iterators to find items in the list and not in the list.
+     */
+    class BufferList {
+        size_t mCapacity;
+        uint32_t mList;
+    public:
+        BufferList(size_t c = SharedBufferStack::NUM_BUFFER_MAX)
+            : mCapacity(c), mList(0) { }
+        status_t add(int value);
+        status_t remove(int value);
+        uint32_t getMask() const { return mList; }
+
+        class const_iterator {
+            friend class BufferList;
+            uint32_t mask, curr;
+            const_iterator(uint32_t mask) :
+                mask(mask), curr(__builtin_clz(mask)) {
+            }
+        public:
+            inline bool operator == (const const_iterator& rhs) const {
+                return mask == rhs.mask;
+            }
+            inline bool operator != (const const_iterator& rhs) const {
+                return mask != rhs.mask;
+            }
+            inline int operator *() const { return curr; }
+            inline const const_iterator& operator ++() {
+                mask &= ~(1<<(31-curr));
+                curr = __builtin_clz(mask);
+                return *this;
+            }
+        };
+
+        inline const_iterator begin() const {
+            return const_iterator(mList);
+        }
+        inline const_iterator end() const   {
+            return const_iterator(0);
+        }
+        inline const_iterator free_begin() const {
+            uint32_t mask = (1 << (32-mCapacity)) - 1;
+            return const_iterator( ~(mList | mask) );
+        }
+    };
+
+    // this protects mNumBuffers and mBufferList
+    mutable RWLock mLock;
+    int mNumBuffers;
+    BufferList mBufferList;
+
     struct UnlockUpdate : public UpdateBase {
         const int lockedBuffer;
         inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
@@ -314,13 +361,6 @@
         inline StatusUpdate(SharedBufferBase* sbb, status_t status);
         inline ssize_t operator()();
     };
-
-    struct ReallocateCondition : public ConditionBase {
-        int buf;
-        inline ReallocateCondition(SharedBufferBase* sbb, int buf);
-        inline bool operator()();
-        static inline const char* name() { return "ReallocateCondition"; }
-    };
 };
 
 // ===========================================================================
@@ -344,13 +384,12 @@
     uint8_t         connected;
     uint8_t         reserved[3];
     uint32_t        pad[7];
-    display_cblk_t  displays[NUM_DISPLAY_MAX];
+    display_cblk_t  displays[SharedBufferStack::NUM_DISPLAY_MAX];
 };
 
 // ---------------------------------------------------------------------------
 
-COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 4096)
-COMPILE_TIME_ASSERT(sizeof(SharedBufferStack) == 128)
+COMPILE_TIME_ASSERT(sizeof(SharedClient) <= 32768)
 COMPILE_TIME_ASSERT(sizeof(surface_flinger_cblk_t) <= 4096)
 
 // ---------------------------------------------------------------------------
diff --git a/include/surfaceflinger/ISurface.h b/include/surfaceflinger/ISurface.h
index 472f759..ddbe03d 100644
--- a/include/surfaceflinger/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -47,13 +47,30 @@
         POST_BUFFER, // one-way transaction
         CREATE_OVERLAY,
         REQUEST_BUFFER,
+        SET_BUFFER_COUNT,
     };
 
 public: 
     DECLARE_META_INTERFACE(Surface);
 
-    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx, int usage) = 0; 
+    /*
+     * requests a new buffer for the given index. If w, h, or format are
+     * null the buffer is created with the parameters assigned to the
+     * surface it is bound to. Otherwise the buffer's parameters are
+     * set to those specified.
+     */
+    virtual sp<GraphicBuffer> requestBuffer(int bufferIdx,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage) = 0;
+
+    /*
+     * sets the number of buffers dequeuable for this surface.
+     */
+    virtual status_t setBufferCount(int bufferCount) = 0;
     
+    // ------------------------------------------------------------------------
+    // Deprecated...
+    // ------------------------------------------------------------------------
+
     class BufferHeap {
     public:
         enum {
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index d1e7785..dd44aa5 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -27,7 +27,7 @@
 
 #include <ui/PixelFormat.h>
 
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 
 namespace android {
 // ----------------------------------------------------------------------------
@@ -85,8 +85,11 @@
     /* create connection with surface flinger, requires
      * ACCESS_SURFACE_FLINGER permission
      */
+    virtual sp<ISurfaceComposerClient> createConnection() = 0;
 
-    virtual sp<ISurfaceFlingerClient> createConnection() = 0;
+    /* create a client connection with surface flinger
+     */
+    virtual sp<ISurfaceComposerClient> createClientConnection() = 0;
 
     /* retrieve the control block */
     virtual sp<IMemoryHeap> getCblk() const = 0;
@@ -123,6 +126,7 @@
         // Java by ActivityManagerService.
         BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
         CREATE_CONNECTION,
+        CREATE_CLIENT_CONNECTION,
         GET_CBLK,
         OPEN_GLOBAL_TRANSACTION,
         CLOSE_GLOBAL_TRANSACTION,
diff --git a/include/surfaceflinger/ISurfaceComposerClient.h b/include/surfaceflinger/ISurfaceComposerClient.h
new file mode 100644
index 0000000..a1e9e04
--- /dev/null
+++ b/include/surfaceflinger/ISurfaceComposerClient.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+#define ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
+#include <ui/PixelFormat.h>
+
+#include <surfaceflinger/ISurface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IMemoryHeap;
+
+typedef int32_t    ClientID;
+typedef int32_t    DisplayID;
+
+// ----------------------------------------------------------------------------
+
+class layer_state_t;
+
+class ISurfaceComposerClient : public IInterface
+{
+public:
+    DECLARE_META_INTERFACE(SurfaceComposerClient);
+
+    struct surface_data_t {
+        int32_t             token;
+        int32_t             identity;
+        uint32_t            width;
+        uint32_t            height;
+        uint32_t            format;
+        status_t readFromParcel(const Parcel& parcel);
+        status_t writeToParcel(Parcel* parcel) const;
+    };
+
+    virtual sp<IMemoryHeap> getControlBlock() const = 0;
+    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const = 0;
+
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual sp<ISurface> createSurface( surface_data_t* data,
+                                        int pid,
+                                        const String8& name,
+                                        DisplayID display,
+                                        uint32_t w,
+                                        uint32_t h,
+                                        PixelFormat format,
+                                        uint32_t flags) = 0;
+
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual status_t    destroySurface(SurfaceID sid) = 0;
+
+    /*
+     * Requires ACCESS_SURFACE_FLINGER permission
+     */
+    virtual status_t    setState(int32_t count, const layer_state_t* states) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+class BnSurfaceComposerClient : public BnInterface<ISurfaceComposerClient>
+{
+public:
+    virtual status_t    onTransact( uint32_t code,
+                                    const Parcel& data,
+                                    Parcel* reply,
+                                    uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_SF_ISURFACE_COMPOSER_CLIENT_H
diff --git a/include/surfaceflinger/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceFlingerClient.h
deleted file mode 100644
index d257645..0000000
--- a/include/surfaceflinger/ISurfaceFlingerClient.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <utils/Errors.h>
-#include <utils/RefBase.h>
-
-#include <binder/IInterface.h>
-
-#include <ui/PixelFormat.h>
-  
-#include <surfaceflinger/ISurface.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-class IMemoryHeap;
-
-typedef int32_t    ClientID;
-typedef int32_t    DisplayID;
-
-// ----------------------------------------------------------------------------
-
-class layer_state_t;
-
-class ISurfaceFlingerClient : public IInterface
-{
-public: 
-    DECLARE_META_INTERFACE(SurfaceFlingerClient);
-
-    struct surface_data_t {
-        int32_t             token;
-        int32_t             identity;
-        uint32_t            width;
-        uint32_t            height;
-        uint32_t            format;
-        status_t readFromParcel(const Parcel& parcel);
-        status_t writeToParcel(Parcel* parcel) const;
-    };
-    
-    virtual sp<IMemoryHeap> getControlBlock() const = 0;
-
-    virtual sp<ISurface> createSurface( surface_data_t* data,
-                                        int pid, 
-                                        const String8& name,
-                                        DisplayID display,
-                                        uint32_t w,
-                                        uint32_t h,
-                                        PixelFormat format,
-                                        uint32_t flags) = 0;
-                                    
-    virtual status_t    destroySurface(SurfaceID sid) = 0;
-
-    virtual status_t    setState(int32_t count, const layer_state_t* states) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnSurfaceFlingerClient : public BnInterface<ISurfaceFlingerClient>
-{
-public:
-    virtual status_t    onTransact( uint32_t code,
-                                    const Parcel& data,
-                                    Parcel* reply,
-                                    uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------------
-
-}; // namespace android
-
-#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 0279d84..7c5a39b 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -20,6 +20,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <utils/KeyedVector.h>
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
@@ -28,12 +29,15 @@
 #include <ui/egl/android_natives.h>
 
 #include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+
+#define ANDROID_VIEW_SURFACE_JNI_ID    "mNativeSurface"
 
 namespace android {
 
 // ---------------------------------------------------------------------------
 
+class GraphicBuffer;
 class GraphicBufferMapper;
 class IOMX;
 class Rect;
@@ -41,6 +45,7 @@
 class SurfaceComposerClient;
 class SharedClient;
 class SharedBufferClient;
+class SurfaceClient;
 
 // ---------------------------------------------------------------------------
 
@@ -56,7 +61,6 @@
     static bool isSameSurface(
             const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs);
         
-    SurfaceID   ID() const      { return mToken; }
     uint32_t    getFlags() const { return mFlags; }
     uint32_t    getIdentity() const { return mIdentity; }
 
@@ -104,7 +108,7 @@
     SurfaceControl(
             const sp<SurfaceComposerClient>& client,
             const sp<ISurface>& surface,
-            const ISurfaceFlingerClient::surface_data_t& data,
+            const ISurfaceComposerClient::surface_data_t& data,
             uint32_t w, uint32_t h, PixelFormat format, uint32_t flags);
 
     ~SurfaceControl();
@@ -128,7 +132,7 @@
 // ---------------------------------------------------------------------------
 
 class Surface 
-    : public EGLNativeBase<android_native_window_t, Surface, RefBase>
+    : public EGLNativeBase<ANativeWindow, Surface, RefBase>
 {
 public:
     struct SurfaceInfo {
@@ -141,17 +145,16 @@
         uint32_t    reserved[2];
     };
 
-    Surface(const Parcel& data);
+    static status_t writeToParcel(
+            const sp<Surface>& control, Parcel* parcel);
+
+    static sp<Surface> readFromParcel(const Parcel& data);
 
     static bool isValid(const sp<Surface>& surface) {
         return (surface != 0) && surface->isValid();
     }
 
-    static bool isSameSurface(
-            const sp<Surface>& lhs, const sp<Surface>& rhs);
-
     bool        isValid();
-    SurfaceID   ID() const          { return mToken; }
     uint32_t    getFlags() const    { return mFlags; }
     uint32_t    getIdentity() const { return mIdentity; }
 
@@ -163,44 +166,43 @@
     // setSwapRectangle() is intended to be used by GL ES clients
     void        setSwapRectangle(const Rect& r);
 
+
 private:
-    // can't be copied
-    Surface& operator = (Surface& rhs);
-    Surface(const Surface& rhs);
-
-    Surface(const sp<SurfaceControl>& control);
-    void init();
-     ~Surface();
-  
-    friend class SurfaceComposerClient;
-    friend class SurfaceControl;
-
-    
+    /*
+     * Android frameworks friends
+     * (eventually this should go away and be replaced by proper APIs)
+     */
     // camera and camcorder need access to the ISurface binder interface for preview
     friend class Camera;
     friend class MediaRecorder;
-    // mediaplayer needs access to ISurface for display
+    // MediaPlayer needs access to ISurface for display
     friend class MediaPlayer;
     friend class IOMX;
     // this is just to be able to write some unit tests
     friend class Test;
 
-    sp<SurfaceComposerClient> getClient() const;
-    sp<ISurface> getISurface() const;
+private:
+    friend class SurfaceComposerClient;
+    friend class SurfaceControl;
 
-    status_t getBufferLocked(int index, int usage);
-   
-           status_t validate() const;
+    // can't be copied
+    Surface& operator = (Surface& rhs);
+    Surface(const Surface& rhs);
 
-    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
-    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
-    
-    static int setSwapInterval(android_native_window_t* window, int interval);
-    static int dequeueBuffer(android_native_window_t* window, android_native_buffer_t** buffer);
-    static int lockBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
-    static int queueBuffer(android_native_window_t* window, android_native_buffer_t* buffer);
-    static int query(android_native_window_t* window, int what, int* value);
-    static int perform(android_native_window_t* window, int operation, ...);
+    Surface(const sp<SurfaceControl>& control);
+    Surface(const Parcel& data, const sp<IBinder>& ref);
+    ~Surface();
+
+
+    /*
+     *  ANativeWindow hooks
+     */
+    static int setSwapInterval(ANativeWindow* window, int interval);
+    static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer);
+    static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer);
+    static int query(ANativeWindow* window, int what, int* value);
+    static int perform(ANativeWindow* window, int operation, ...);
 
     int dequeueBuffer(android_native_buffer_t** buffer);
     int lockBuffer(android_native_buffer_t* buffer);
@@ -208,44 +210,91 @@
     int query(int what, int* value);
     int perform(int operation, va_list args);
 
-    status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
-
     void dispatch_setUsage(va_list args);
     int  dispatch_connect(va_list args);
     int  dispatch_disconnect(va_list args);
+    int  dispatch_crop(va_list args);
+    int  dispatch_set_buffer_count(va_list args);
+    int  dispatch_set_buffers_geometry(va_list args);
+    int  dispatch_set_buffers_transform(va_list args);
     
     void setUsage(uint32_t reqUsage);
     int  connect(int api);
     int  disconnect(int api);
+    int  crop(Rect const* rect);
+    int  setBufferCount(int bufferCount);
+    int  setBuffersGeometry(int w, int h, int format);
+    int  setBuffersTransform(int transform);
 
-    uint32_t getUsage() const;
-    int      getConnectedApi() const;
+    /*
+     *  private stuff...
+     */
+    void init();
+    status_t validate() const;
+    sp<ISurface> getISurface() const;
+
+    inline const GraphicBufferMapper& getBufferMapper() const { return mBufferMapper; }
+    inline GraphicBufferMapper& getBufferMapper() { return mBufferMapper; }
+
+    status_t getBufferLocked(int index,
+            uint32_t w, uint32_t h, uint32_t format, uint32_t usage);
+    int getBufferIndex(const sp<GraphicBuffer>& buffer) const;
+
+    int getConnectedApi() const;
     
+    bool needNewBuffer(int bufIdx,
+            uint32_t *pWidth, uint32_t *pHeight,
+            uint32_t *pFormat, uint32_t *pUsage) const;
+
+    static void cleanCachedSurfaces();
+
+    class BufferInfo {
+        uint32_t mWidth;
+        uint32_t mHeight;
+        uint32_t mFormat;
+        uint32_t mUsage;
+        mutable uint32_t mDirty;
+        enum {
+            GEOMETRY = 0x01
+        };
+    public:
+        BufferInfo();
+        void set(uint32_t w, uint32_t h, uint32_t format);
+        void set(uint32_t usage);
+        void get(uint32_t *pWidth, uint32_t *pHeight,
+                uint32_t *pFormat, uint32_t *pUsage) const;
+        bool validateBuffer(const sp<GraphicBuffer>& buffer) const;
+    };
+
     // constants
-    sp<SurfaceComposerClient>   mClient;
+    GraphicBufferMapper&        mBufferMapper;
+    SurfaceClient&              mClient;
+    SharedBufferClient*         mSharedBufferClient;
+    status_t                    mInitCheck;
     sp<ISurface>                mSurface;
-    SurfaceID                   mToken;
     uint32_t                    mIdentity;
     PixelFormat                 mFormat;
     uint32_t                    mFlags;
-    GraphicBufferMapper&        mBufferMapper;
-    SharedBufferClient*         mSharedBufferClient;
 
     // protected by mSurfaceLock
     Rect                        mSwapRectangle;
-    uint32_t                    mUsage;
     int                         mConnected;
+    Rect                        mNextBufferCrop;
+    uint32_t                    mNextBufferTransform;
+    BufferInfo                  mBufferInfo;
     
     // protected by mSurfaceLock. These are also used from lock/unlock
     // but in that case, they must be called form the same thread.
-    sp<GraphicBuffer>           mBuffers[2];
     mutable Region              mDirtyRegion;
 
     // must be used from the lock/unlock thread
     sp<GraphicBuffer>           mLockedBuffer;
     sp<GraphicBuffer>           mPostedBuffer;
     mutable Region              mOldDirtyRegion;
-    bool                        mNeedFullUpdate;
+    bool                        mReserved;
+
+    // only used from dequeueBuffer()
+    Vector< sp<GraphicBuffer> > mBuffers;
 
     // query() must be called from dequeueBuffer() thread
     uint32_t                    mWidth;
@@ -254,6 +303,10 @@
     // Inherently thread-safe
     mutable Mutex               mSurfaceLock;
     mutable Mutex               mApiLock;
+
+    // A cache of Surface objects that have been deserialized into this process.
+    static Mutex sCachedSurfacesLock;
+    static DefaultKeyedVector<wp<IBinder>, wp<Surface> > sCachedSurfaces;
 };
 
 }; // namespace android
diff --git a/include/surfaceflinger/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
index 9d0f0cb..8773d71 100644
--- a/include/surfaceflinger/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -22,8 +22,9 @@
 
 #include <binder/IBinder.h>
 
-#include <utils/SortedVector.h>
 #include <utils/RefBase.h>
+#include <utils/Singleton.h>
+#include <utils/SortedVector.h>
 #include <utils/threads.h>
 
 #include <ui/PixelFormat.h>
@@ -39,8 +40,26 @@
 class SharedClient;
 class ISurfaceComposer;
 class DisplayInfo;
+class surface_flinger_cblk_t;
 
-class SurfaceComposerClient : virtual public RefBase
+// ---------------------------------------------------------------------------
+
+class ComposerService : public Singleton<ComposerService>
+{
+    // these are constants
+    sp<ISurfaceComposer> mComposerService;
+    sp<IMemoryHeap> mServerCblkMemory;
+    surface_flinger_cblk_t volatile* mServerCblk;
+    ComposerService();
+    friend class Singleton<ComposerService>;
+public:
+    static sp<ISurfaceComposer> getComposerService();
+    static surface_flinger_cblk_t const volatile * getControlBlock();
+};
+
+// ---------------------------------------------------------------------------
+
+class SurfaceComposerClient : public RefBase
 {
 public:    
                 SurfaceComposerClient();
@@ -52,10 +71,6 @@
     // Return the connection of this client
     sp<IBinder> connection() const;
     
-    // Retrieve a client for an existing connection.
-    static sp<SurfaceComposerClient>
-                clientForConnection(const sp<IBinder>& conn);
-
     // Forcibly remove connection before all references have gone away.
     void        dispose();
 
@@ -123,13 +138,6 @@
     status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
             void* cookie = NULL, uint32_t flags = 0);
 
-private:
-    friend class Surface;
-    friend class SurfaceControl;
-    
-    SurfaceComposerClient(const sp<ISurfaceComposer>& sm, 
-            const sp<IBinder>& conn);
-
     status_t    hide(SurfaceID id);
     status_t    show(SurfaceID id, int32_t layer = -1);
     status_t    freeze(SurfaceID id);
@@ -142,32 +150,26 @@
     status_t    setMatrix(SurfaceID id, float dsdx, float dtdx, float dsdy, float dtdy);
     status_t    setPosition(SurfaceID id, int32_t x, int32_t y);
     status_t    setSize(SurfaceID id, uint32_t w, uint32_t h);
-    
-    void        signalServer();
-
     status_t    destroySurface(SurfaceID sid);
 
-    void        _init(const sp<ISurfaceComposer>& sm,
-                    const sp<ISurfaceFlingerClient>& conn);
-
-    inline layer_state_t*   _get_state_l(SurfaceID id);
-    layer_state_t*          _lockLayerState(SurfaceID id);
-    inline void             _unlockLayerState();
+private:
+    virtual void onFirstRef();
+    inline layer_state_t*   get_state_l(SurfaceID id);
+    layer_state_t*          lockLayerState(SurfaceID id);
+    inline void             unlockLayerState();
 
     mutable     Mutex                               mLock;
-                layer_state_t*                      mPrebuiltLayerState;
                 SortedVector<layer_state_t>         mStates;
                 int32_t                             mTransactionOpen;
+                layer_state_t*                      mPrebuiltLayerState;
 
                 // these don't need to be protected because they never change
                 // after assignment
                 status_t                    mStatus;
-                SharedClient*               mControl;
-                sp<IMemoryHeap>             mControlMemory;
-                sp<ISurfaceFlingerClient>   mClient;
-                sp<ISurfaceComposer>        mSignalServer;
+                sp<ISurfaceComposerClient>  mClient;
 };
 
+// ---------------------------------------------------------------------------
 }; // namespace android
 
 #endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index 3b18c77..d6b09dc 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -18,6 +18,7 @@
 #ifndef _RUNTIME_EVENT_HUB_H
 #define _RUNTIME_EVENT_HUB_H
 
+#include <android/input.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 #include <utils/Log.h>
@@ -27,6 +28,31 @@
 
 #include <linux/input.h>
 
+/* These constants are not defined in linux/input.h but they are part of the multitouch
+ * input protocol. */
+
+#define ABS_MT_TOUCH_MAJOR 0x30  /* Major axis of touching ellipse */
+#define ABS_MT_TOUCH_MINOR 0x31  /* Minor axis (omit if circular) */
+#define ABS_MT_WIDTH_MAJOR 0x32  /* Major axis of approaching ellipse */
+#define ABS_MT_WIDTH_MINOR 0x33  /* Minor axis (omit if circular) */
+#define ABS_MT_ORIENTATION 0x34  /* Ellipse orientation */
+#define ABS_MT_POSITION_X 0x35   /* Center X ellipse position */
+#define ABS_MT_POSITION_Y 0x36   /* Center Y ellipse position */
+#define ABS_MT_TOOL_TYPE 0x37    /* Type of touching device (finger, pen, ...) */
+#define ABS_MT_BLOB_ID 0x38      /* Group a set of packets as a blob */
+#define ABS_MT_TRACKING_ID 0x39  /* Unique ID of initiated contact */
+#define ABS_MT_PRESSURE 0x3a     /* Pressure on contact area */
+
+#define MT_TOOL_FINGER 0 /* Identifies a finger */
+#define MT_TOOL_PEN 1    /* Identifies a pen */
+
+#define SYN_MT_REPORT 2
+
+/* Convenience constants. */
+
+#define BTN_FIRST 0x100  // first button scancode
+#define BTN_LAST 0x15f   // last button scancode
+
 struct pollfd;
 
 namespace android {
@@ -34,73 +60,162 @@
 class KeyLayoutMap;
 
 /*
- * Grand Central Station for events.  With a single call to waitEvent()
- * you can wait for:
- *  - input events from the keypad of a real device
- *  - input events and meta-events (e.g. "quit") from the simulator
- *  - synthetic events from the runtime (e.g. "URL fetch completed")
- *  - real or forged "vsync" events
- *
- * Do not instantiate this class.  Instead, call startUp().
+ * A raw event as retrieved from the EventHub.
  */
-class EventHub : public RefBase
-{
+struct RawEvent {
+    nsecs_t when;
+    int32_t deviceId;
+    int32_t type;
+    int32_t scanCode;
+    int32_t keyCode;
+    int32_t value;
+    uint32_t flags;
+};
+
+/* Describes an absolute axis. */
+struct RawAbsoluteAxisInfo {
+    bool valid; // true if the information is valid, false otherwise
+
+    int32_t minValue;  // minimum value
+    int32_t maxValue;  // maximum value
+    int32_t flat;      // center flat position, eg. flat == 8 means center is between -8 and 8
+    int32_t fuzz;      // error tolerance, eg. fuzz == 4 means value is +/- 4 due to noise
+
+    inline int32_t getRange() { return maxValue - minValue; }
+
+    inline void clear() {
+        valid = false;
+        minValue = 0;
+        maxValue = 0;
+        flat = 0;
+        fuzz = 0;
+    }
+};
+
+/*
+ * Input device classes.
+ */
+enum {
+    /* The input device is a keyboard. */
+    INPUT_DEVICE_CLASS_KEYBOARD      = 0x00000001,
+
+    /* The input device is an alpha-numeric keyboard (not just a dial pad). */
+    INPUT_DEVICE_CLASS_ALPHAKEY      = 0x00000002,
+
+    /* The input device is a touchscreen (either single-touch or multi-touch). */
+    INPUT_DEVICE_CLASS_TOUCHSCREEN   = 0x00000004,
+
+    /* The input device is a trackball. */
+    INPUT_DEVICE_CLASS_TRACKBALL     = 0x00000008,
+
+    /* The input device is a multi-touch touchscreen. */
+    INPUT_DEVICE_CLASS_TOUCHSCREEN_MT= 0x00000010,
+
+    /* The input device is a directional pad (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.
-    enum {
-        CLASS_KEYBOARD      = 0x00000001,
-        CLASS_ALPHAKEY      = 0x00000002,
-        CLASS_TOUCHSCREEN   = 0x00000004,
-        CLASS_TRACKBALL     = 0x00000008,
-        CLASS_TOUCHSCREEN_MT= 0x00000010,
-        CLASS_DPAD          = 0x00000020
-    };
-    uint32_t getDeviceClasses(int32_t deviceId) const;
-    
-    String8 getDeviceName(int32_t deviceId) const;
-    
-    int getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
-            int* outMaxValue, int* outFlat, int* outFuzz) const;
-        
-    int getSwitchState(int sw) const;
-    int getSwitchState(int32_t deviceId, int sw) const;
-    
-    int getScancodeState(int key) const;
-    int getScancodeState(int32_t deviceId, int key) const;
-    
-    int getKeycodeState(int key) const;
-    int getKeycodeState(int32_t deviceId, int key) const;
-    
-    status_t scancodeToKeycode(int32_t deviceId, int scancode,
-            int32_t* outKeycode, uint32_t* outFlags) const;
-
-    // exclude a particular device from opening
-    // this can be used to ignore input devices for sensors
-    void addExcludedDevice(const char* deviceName);
-
-    // special type codes when devices are added/removed.
+    // Synthetic raw event type codes produced when devices are added or removed.
     enum {
         DEVICE_ADDED = 0x10000000,
         DEVICE_REMOVED = 0x20000000
     };
-    
-    // examine key input devices for specific framework keycode support
-    bool hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags);
 
-    virtual bool getEvent(int32_t* outDeviceId, int32_t* outType,
-            int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
-            int32_t* outValue, nsecs_t* outWhen);
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0;
+
+    virtual String8 getDeviceName(int32_t deviceId) const = 0;
+
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const = 0;
+
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const = 0;
+
+    // exclude a particular device from opening
+    // this can be used to ignore input devices for sensors
+    virtual void addExcludedDevice(const char* deviceName) = 0;
+
+    /*
+     * Wait for the next event to become available and return it.
+     * After returning, the EventHub holds onto a wake lock until the next call to getEvent.
+     * This ensures that the device will not go to sleep while the event is being processed.
+     * If the device needs to remain awake longer than that, then the caller is responsible
+     * for taking care of it (say, by poking the power manager user activity timer).
+     */
+    virtual bool getEvent(RawEvent* outEvent) = 0;
+
+    /*
+     * Query current input state.
+     */
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const = 0;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const = 0;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const = 0;
+
+    /*
+     * Examine key input devices for specific framework keycode support
+     */
+    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+            uint8_t* outFlags) const = 0;
+};
+
+class EventHub : public EventHubInterface
+{
+public:
+    EventHub();
+
+    status_t errorCheck() const;
+
+    virtual uint32_t getDeviceClasses(int32_t deviceId) const;
+    
+    virtual String8 getDeviceName(int32_t deviceId) const;
+    
+    virtual status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+            RawAbsoluteAxisInfo* outAxisInfo) const;
+
+    virtual status_t scancodeToKeycode(int32_t deviceId, int scancode,
+            int32_t* outKeycode, uint32_t* outFlags) const;
+
+    virtual void addExcludedDevice(const char* deviceName);
+
+    virtual int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const;
+    virtual int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const;
+    virtual int32_t getSwitchState(int32_t deviceId, int32_t sw) const;
+
+    virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags) const;
+
+    virtual bool getEvent(RawEvent* outEvent);
 
 protected:
     virtual ~EventHub();
     
 private:
     bool openPlatformInput(void);
-    int32_t convertDeviceKey_TI_P2(int code);
 
     int open_device(const char *device);
     int close_device(const char *device);
@@ -117,6 +232,7 @@
         uint8_t*        keyBitmask;
         KeyLayoutMap*   layoutMap;
         String8         keylayoutFilename;
+        int             fd;
         device_t*       next;
         
         device_t(int32_t _id, const char* _path, const char* name);
@@ -126,6 +242,12 @@
     device_t* getDevice(int32_t deviceId) const;
     bool hasKeycode(device_t* device, int keycode) const;
     
+    int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const;
+    int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const;
+    int32_t getSwitchStateLocked(device_t* device, int32_t sw) const;
+    bool markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags) const;
+
     // Protect all internal state.
     mutable Mutex   mLock;
     
@@ -151,8 +273,14 @@
 
     // device ids that report particular switches.
 #ifdef EV_SW
-    int32_t         mSwitches[SW_MAX+1];
+    int32_t         mSwitches[SW_MAX + 1];
 #endif
+
+    static const int INPUT_BUFFER_SIZE = 64;
+    struct input_event mInputBufferData[INPUT_BUFFER_SIZE];
+    int32_t mInputBufferIndex;
+    int32_t mInputBufferCount;
+    int32_t mInputDeviceIndex;
 };
 
 }; // namespace android
diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h
index 8ea3ab9..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..b587e94
--- /dev/null
+++ b/include/ui/Input.h
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_H
+#define _UI_INPUT_H
+
+/**
+ * Native input event structures.
+ */
+
+#include <android/input.h>
+#include <utils/Vector.h>
+#include <utils/KeyedVector.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+/*
+ * Additional private constants not defined in ndk/ui/input.h.
+ */
+enum {
+    /*
+     * Private control to determine when an app is tracking a key sequence.
+     */
+    AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
+};
+
+/*
+ * Maximum number of pointers supported per motion event.
+ */
+#define MAX_POINTERS 10
+
+/*
+ * Declare a concrete type for the NDK's input event forward declaration.
+ */
+struct AInputEvent {
+    virtual ~AInputEvent() { }
+};
+
+/*
+ * Declare a concrete type for the NDK's input device forward declaration.
+ */
+struct AInputDevice {
+    virtual ~AInputDevice() { }
+};
+
+
+namespace android {
+
+/*
+ * Flags that flow alongside events in the input dispatch system to help with certain
+ * policy decisions such as waking from device sleep.
+ */
+enum {
+    /* These flags originate in RawEvents and are generally set in the key map. */
+
+    POLICY_FLAG_WAKE = 0x00000001,
+    POLICY_FLAG_WAKE_DROPPED = 0x00000002,
+    POLICY_FLAG_SHIFT = 0x00000004,
+    POLICY_FLAG_CAPS_LOCK = 0x00000008,
+    POLICY_FLAG_ALT = 0x00000010,
+    POLICY_FLAG_ALT_GR = 0x00000020,
+    POLICY_FLAG_MENU = 0x00000040,
+    POLICY_FLAG_LAUNCHER = 0x00000080,
+
+    POLICY_FLAG_RAW_MASK = 0x0000ffff,
+
+    /* These flags are set by the input dispatcher. */
+
+    // Indicates that the input event was injected.
+    POLICY_FLAG_INJECTED = 0x01000000,
+
+    /* These flags are set by the input reader policy as it intercepts each event. */
+
+    // Indicates that the screen was off when the event was received and the event
+    // should wake the device.
+    POLICY_FLAG_WOKE_HERE = 0x10000000,
+
+    // Indicates that the screen was dim when the event was received and the event
+    // should brighten the device.
+    POLICY_FLAG_BRIGHT_HERE = 0x20000000,
+};
+
+/*
+ * Describes the basic configuration of input devices that are present.
+ */
+struct InputConfiguration {
+    enum {
+        TOUCHSCREEN_UNDEFINED = 0,
+        TOUCHSCREEN_NOTOUCH = 1,
+        TOUCHSCREEN_STYLUS = 2,
+        TOUCHSCREEN_FINGER = 3
+    };
+
+    enum {
+        KEYBOARD_UNDEFINED = 0,
+        KEYBOARD_NOKEYS = 1,
+        KEYBOARD_QWERTY = 2,
+        KEYBOARD_12KEY = 3
+    };
+
+    enum {
+        NAVIGATION_UNDEFINED = 0,
+        NAVIGATION_NONAV = 1,
+        NAVIGATION_DPAD = 2,
+        NAVIGATION_TRACKBALL = 3,
+        NAVIGATION_WHEEL = 4
+    };
+
+    int32_t touchScreen;
+    int32_t keyboard;
+    int32_t navigation;
+};
+
+/*
+ * Pointer coordinate data.
+ */
+struct PointerCoords {
+    float x;
+    float y;
+    float pressure;
+    float size;
+    float touchMajor;
+    float touchMinor;
+    float toolMajor;
+    float toolMinor;
+    float orientation;
+};
+
+/*
+ * Input events.
+ */
+class InputEvent : public AInputEvent {
+public:
+    virtual ~InputEvent() { }
+
+    virtual int32_t getType() const = 0;
+
+    inline int32_t getDeviceId() const { return mDeviceId; }
+
+    inline int32_t getSource() const { return mSource; }
+    
+protected:
+    void initialize(int32_t deviceId, int32_t source);
+    void initialize(const InputEvent& from);
+
+private:
+    int32_t mDeviceId;
+    int32_t mSource;
+};
+
+/*
+ * Key events.
+ */
+class KeyEvent : public InputEvent {
+public:
+    virtual ~KeyEvent() { }
+
+    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_KEY; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    inline int32_t getKeyCode() const { return mKeyCode; }
+
+    inline int32_t getScanCode() const { return mScanCode; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline int32_t getRepeatCount() const { return mRepeatCount; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline nsecs_t getEventTime() const { return mEventTime; }
+
+    // Return true if this event may have a default action implementation.
+    static bool hasDefaultAction(int32_t keyCode);
+    bool hasDefaultAction() const;
+
+    // Return true if this event represents a system key.
+    static bool isSystemKey(int32_t keyCode);
+    bool isSystemKey() const;
+    
+    void initialize(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t keyCode,
+            int32_t scanCode,
+            int32_t metaState,
+            int32_t repeatCount,
+            nsecs_t downTime,
+            nsecs_t eventTime);
+    void initialize(const KeyEvent& from);
+
+private:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mKeyCode;
+    int32_t mScanCode;
+    int32_t mMetaState;
+    int32_t mRepeatCount;
+    nsecs_t mDownTime;
+    nsecs_t mEventTime;
+};
+
+/*
+ * Motion events.
+ */
+class MotionEvent : public InputEvent {
+public:
+    virtual ~MotionEvent() { }
+
+    virtual int32_t getType() const { return AINPUT_EVENT_TYPE_MOTION; }
+
+    inline int32_t getAction() const { return mAction; }
+
+    inline int32_t getFlags() const { return mFlags; }
+
+    inline int32_t getEdgeFlags() const { return mEdgeFlags; }
+
+    inline int32_t getMetaState() const { return mMetaState; }
+
+    inline float getXOffset() const { return mXOffset; }
+
+    inline float getYOffset() const { return mYOffset; }
+
+    inline float getXPrecision() const { return mXPrecision; }
+
+    inline float getYPrecision() const { return mYPrecision; }
+
+    inline nsecs_t getDownTime() const { return mDownTime; }
+
+    inline size_t getPointerCount() const { return mPointerIds.size(); }
+
+    inline int32_t getPointerId(size_t pointerIndex) const { return mPointerIds[pointerIndex]; }
+
+    inline nsecs_t getEventTime() const { return mSampleEventTimes[getHistorySize()]; }
+
+    inline float getRawX(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).x;
+    }
+
+    inline float getRawY(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).y;
+    }
+
+    inline float getX(size_t pointerIndex) const {
+        return getRawX(pointerIndex) + mXOffset;
+    }
+
+    inline float getY(size_t pointerIndex) const {
+        return getRawY(pointerIndex) + mYOffset;
+    }
+
+    inline float getPressure(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).pressure;
+    }
+
+    inline float getSize(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).size;
+    }
+
+    inline float getTouchMajor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).touchMajor;
+    }
+
+    inline float getTouchMinor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).touchMinor;
+    }
+
+    inline float getToolMajor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).toolMajor;
+    }
+
+    inline float getToolMinor(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).toolMinor;
+    }
+
+    inline float getOrientation(size_t pointerIndex) const {
+        return getCurrentPointerCoords(pointerIndex).orientation;
+    }
+
+    inline size_t getHistorySize() const { return mSampleEventTimes.size() - 1; }
+
+    inline nsecs_t getHistoricalEventTime(size_t historicalIndex) const {
+        return mSampleEventTimes[historicalIndex];
+    }
+
+    inline float getHistoricalRawX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).x;
+    }
+
+    inline float getHistoricalRawY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).y;
+    }
+
+    inline float getHistoricalX(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalRawX(pointerIndex, historicalIndex) + mXOffset;
+    }
+
+    inline float getHistoricalY(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalRawY(pointerIndex, historicalIndex) + mYOffset;
+    }
+
+    inline float getHistoricalPressure(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).pressure;
+    }
+
+    inline float getHistoricalSize(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).size;
+    }
+
+    inline float getHistoricalTouchMajor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMajor;
+    }
+
+    inline float getHistoricalTouchMinor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).touchMinor;
+    }
+
+    inline float getHistoricalToolMajor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMajor;
+    }
+
+    inline float getHistoricalToolMinor(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).toolMinor;
+    }
+
+    inline float getHistoricalOrientation(size_t pointerIndex, size_t historicalIndex) const {
+        return getHistoricalPointerCoords(pointerIndex, historicalIndex).orientation;
+    }
+
+    void initialize(
+            int32_t deviceId,
+            int32_t source,
+            int32_t action,
+            int32_t flags,
+            int32_t edgeFlags,
+            int32_t metaState,
+            float xOffset,
+            float yOffset,
+            float xPrecision,
+            float yPrecision,
+            nsecs_t downTime,
+            nsecs_t eventTime,
+            size_t pointerCount,
+            const int32_t* pointerIds,
+            const PointerCoords* pointerCoords);
+
+    void addSample(
+            nsecs_t eventTime,
+            const PointerCoords* pointerCoords);
+
+    void offsetLocation(float xOffset, float yOffset);
+
+    // Low-level accessors.
+    inline const int32_t* getPointerIds() const { return mPointerIds.array(); }
+    inline const nsecs_t* getSampleEventTimes() const { return mSampleEventTimes.array(); }
+    inline const PointerCoords* getSamplePointerCoords() const {
+            return mSamplePointerCoords.array();
+    }
+
+private:
+    int32_t mAction;
+    int32_t mFlags;
+    int32_t mEdgeFlags;
+    int32_t mMetaState;
+    float mXOffset;
+    float mYOffset;
+    float mXPrecision;
+    float mYPrecision;
+    nsecs_t mDownTime;
+    Vector<int32_t> mPointerIds;
+    Vector<nsecs_t> mSampleEventTimes;
+    Vector<PointerCoords> mSamplePointerCoords;
+
+    inline const PointerCoords& getCurrentPointerCoords(size_t pointerIndex) const {
+        return mSamplePointerCoords[getHistorySize() * getPointerCount() + pointerIndex];
+    }
+
+    inline const PointerCoords& getHistoricalPointerCoords(
+            size_t pointerIndex, size_t historicalIndex) const {
+        return mSamplePointerCoords[historicalIndex * getPointerCount() + pointerIndex];
+    }
+};
+
+/*
+ * Input event factory.
+ */
+class InputEventFactoryInterface {
+protected:
+    virtual ~InputEventFactoryInterface() { }
+
+public:
+    InputEventFactoryInterface() { }
+
+    virtual KeyEvent* createKeyEvent() = 0;
+    virtual MotionEvent* createMotionEvent() = 0;
+};
+
+/*
+ * A simple input event factory implementation that uses a single preallocated instance
+ * of each type of input event that are reused for each request.
+ */
+class PreallocatedInputEventFactory : public InputEventFactoryInterface {
+public:
+    PreallocatedInputEventFactory() { }
+    virtual ~PreallocatedInputEventFactory() { }
+
+    virtual KeyEvent* createKeyEvent() { return & mKeyEvent; }
+    virtual MotionEvent* createMotionEvent() { return & mMotionEvent; }
+
+private:
+    KeyEvent mKeyEvent;
+    MotionEvent mMotionEvent;
+};
+
+/*
+ * Describes the characteristics and capabilities of an input device.
+ */
+class InputDeviceInfo {
+public:
+    InputDeviceInfo();
+    InputDeviceInfo(const InputDeviceInfo& other);
+    ~InputDeviceInfo();
+
+    struct MotionRange {
+        float min;
+        float max;
+        float flat;
+        float fuzz;
+    };
+
+    void initialize(int32_t id, const String8& name);
+
+    inline int32_t getId() const { return mId; }
+    inline const String8 getName() const { return mName; }
+    inline uint32_t getSources() const { return mSources; }
+
+    const MotionRange* getMotionRange(int32_t rangeType) const;
+
+    void addSource(uint32_t source);
+    void addMotionRange(int32_t rangeType, float min, float max, float flat, float fuzz);
+    void addMotionRange(int32_t rangeType, const MotionRange& range);
+
+    inline void setKeyboardType(int32_t keyboardType) { mKeyboardType = keyboardType; }
+    inline int32_t getKeyboardType() const { return mKeyboardType; }
+
+    inline const KeyedVector<int32_t, MotionRange> getMotionRanges() const {
+        return mMotionRanges;
+    }
+
+private:
+    int32_t mId;
+    String8 mName;
+    uint32_t mSources;
+    int32_t mKeyboardType;
+
+    KeyedVector<int32_t, MotionRange> mMotionRanges;
+};
+
+
+} // namespace android
+
+#endif // _UI_INPUT_H
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
new file mode 100644
index 0000000..96b4fae
--- /dev/null
+++ b/include/ui/InputDispatcher.h
@@ -0,0 +1,1003 @@
+/*
+ * 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 <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 a KeyEvent or MotionEvent is being canceled.
+         * In the case of a key event, it should be delivered with flag
+         * AKEY_EVENT_FLAG_CANCELED set.
+         * In the case of a motion event, it should be delivered with action
+         * AMOTION_EVENT_ACTION_CANCEL instead. */
+        FLAG_CANCEL = 0x04,
+
+        /* This flag indicates that the target of a MotionEvent is partly or wholly
+         * obscured by another visible window above it.  The motion event should be
+         * delivered with flag AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */
+        FLAG_WINDOW_IS_OBSCURED = 0x08,
+    };
+
+    // The input channel to be targeted.
+    sp<InputChannel> inputChannel;
+
+    // Flags for the input target.
+    int32_t flags;
+
+    // The x and y offset to add to a MotionEvent as it is delivered.
+    // (ignored for KeyEvents)
+    float xOffset, yOffset;
+};
+
+
+/*
+ * 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_IMMERSIVE = 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,
+        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 visibleFrameIntersects(const InputWindow* other) const;
+    bool touchableAreaContainsPoint(int32_t x, int32_t y) 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;
+
+    /* 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;
+
+    /* Poke user activity for an event dispatched to a window. */
+    virtual void pokeUserActivity(nsecs_t eventTime, int32_t windowType, 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;
+
+    /* 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 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 EventEntry : Link<EventEntry> {
+        enum {
+            TYPE_SENTINEL,
+            TYPE_CONFIGURATION_CHANGED,
+            TYPE_KEY,
+            TYPE_MOTION
+        };
+
+        int32_t refCount;
+        int32_t type;
+        nsecs_t eventTime;
+
+        int32_t injectionResult;  // initially INPUT_EVENT_INJECTION_PENDING
+        bool    injectionIsAsync; // set to true if injection is not waiting for the result
+        int32_t injectorPid;      // -1 if not injected
+        int32_t injectorUid;      // -1 if not injected
+
+        bool dispatchInProgress; // initially false, set to true while dispatching
+        int32_t pendingForegroundDispatches; // the number of foreground dispatches in progress
+
+        inline bool isInjected() { return injectorPid >= 0; }
+
+        void recycle();
+    };
+
+    struct ConfigurationChangedEntry : EventEntry {
+    };
+
+    struct KeyEntry : EventEntry {
+        int32_t deviceId;
+        int32_t source;
+        uint32_t policyFlags;
+        int32_t action;
+        int32_t flags;
+        int32_t keyCode;
+        int32_t scanCode;
+        int32_t metaState;
+        int32_t repeatCount;
+        nsecs_t downTime;
+
+        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
+
+        void recycle();
+    };
+
+    struct MotionSample {
+        MotionSample* next;
+
+        nsecs_t eventTime;
+        PointerCoords pointerCoords[MAX_POINTERS];
+    };
+
+    struct MotionEntry : EventEntry {
+        int32_t deviceId;
+        int32_t source;
+        uint32_t policyFlags;
+        int32_t action;
+        int32_t flags;
+        int32_t metaState;
+        int32_t edgeFlags;
+        float xPrecision;
+        float yPrecision;
+        nsecs_t downTime;
+        uint32_t pointerCount;
+        int32_t pointerIds[MAX_POINTERS];
+
+        // Linked list of motion samples associated with this motion event.
+        MotionSample firstSample;
+        MotionSample* lastSample;
+
+        uint32_t countSamples() const;
+    };
+
+    // Tracks the progress of dispatching a particular event to a particular connection.
+    struct DispatchEntry : Link<DispatchEntry> {
+        EventEntry* eventEntry; // the event to dispatch
+        int32_t targetFlags;
+        float xOffset;
+        float yOffset;
+
+        // 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;
+        }
+    };
+
+    // 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 windowType;
+        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();
+
+        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 releaseEventEntry(EventEntry* entry);
+        void releaseConfigurationChangedEntry(ConfigurationChangedEntry* entry);
+        void releaseKeyEntry(KeyEntry* entry);
+        void releaseMotionEntry(MotionEntry* entry);
+        void releaseDispatchEntry(DispatchEntry* entry);
+        void releaseCommandEntry(CommandEntry* entry);
+
+        void appendMotionSample(MotionEntry* motionEntry,
+                nsecs_t eventTime, const PointerCoords* pointerCoords);
+
+    private:
+        Pool<ConfigurationChangedEntry> mConfigurationChangeEntryPool;
+        Pool<KeyEntry> mKeyEntryPool;
+        Pool<MotionEntry> mMotionEntryPool;
+        Pool<MotionSample> mMotionSamplePool;
+        Pool<DispatchEntry> mDispatchEntryPool;
+        Pool<CommandEntry> mCommandEntryPool;
+
+        void initializeEventEntry(EventEntry* entry, int32_t type, nsecs_t eventTime);
+    };
+
+    /* 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
+        };
+
+        InputState();
+        ~InputState();
+
+        // Returns true if there is no state to be canceled.
+        bool isNeutral() const;
+
+        // Returns true if the input state believes it is out of sync.
+        bool isOutOfSync() const;
+
+        // Sets the input state to be out of sync if it is not neutral.
+        void setOutOfSync();
+
+        // Resets the input state out of sync flag.
+        void resetOutOfSync();
+
+        // 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.
+        void synthesizeCancelationEvents(Allocator* allocator,
+                Vector<EventEntry*>& outEvents) const;
+
+        // Clears the current state.
+        void clear();
+
+    private:
+        bool mIsOutOfSync;
+
+        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;
+    };
+
+    /* 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();
+    };
+
+    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);
+
+    // App switch latency optimization.
+    nsecs_t mAppSwitchDueTime;
+
+    static bool isAppSwitchKey(int32_t keyCode);
+    bool isAppSwitchPendingLocked();
+    bool detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry);
+    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;
+    EventEntry* createEntryFromInjectedInputEventLocked(const InputEvent* event);
+    void setInjectionResultLocked(EventEntry* entry, int32_t injectionResult);
+
+    Condition mInjectionSyncFinishedCondition;
+    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);
+    bool isEventFromReliableSourceLocked(EventEntry* entry);
+
+    // Dispatch state.
+    bool mDispatchEnabled;
+    bool mDispatchFrozen;
+    Vector<InputWindow> mWindows;
+    Vector<InputWindow*> mWallpaperWindows;
+
+    // Focus tracking for keys, trackball, etc.
+    InputWindow* mFocusedWindow;
+
+    // Focus tracking for touch.
+    bool mTouchDown;
+    InputWindow* mTouchedWindow;                   // primary target for current down
+    bool mTouchedWindowIsObscured;                 // true if other windows may obscure the target
+    Vector<InputWindow*> mTouchedWallpaperWindows; // wallpaper targets
+    struct OutsideTarget {
+        InputWindow* window;
+        bool obscured;
+    };
+    Vector<OutsideTarget> mTempTouchedOutsideTargets; // temporary outside touch targets
+    Vector<sp<InputChannel> > mTempTouchedWallpaperChannels; // temporary wallpaper targets
+
+    // 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,
+            bool dropEvent, nsecs_t* nextWakeupTime);
+    bool dispatchMotionLocked(
+            nsecs_t currentTime, MotionEntry* entry,
+            bool dropEvent, 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;
+    int32_t mCurrentInputWindowType;
+    sp<InputChannel> mCurrentInputChannel;
+
+    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(const InputWindow* window);
+    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 findFocusedWindowLocked(nsecs_t currentTime, const EventEntry* entry,
+            nsecs_t* nextWakeupTime, InputWindow** outWindow);
+    int32_t findTouchedWindowLocked(nsecs_t currentTime, const MotionEntry* entry,
+            nsecs_t* nextWakeupTime, InputWindow** outWindow);
+
+    void addWindowTargetLocked(const InputWindow* window, int32_t targetFlags);
+    void addMonitoringTargetsLocked();
+    void pokeUserActivityLocked(nsecs_t eventTime, int32_t windowType, int32_t eventType);
+    bool checkInjectionPermission(const InputWindow* window,
+            int32_t injectorPid, int32_t injectorUid);
+    bool isWindowObscuredLocked(const InputWindow* window);
+    bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
+    void releaseTouchedWindowLocked();
+    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 abortDispatchCycleLocked(nsecs_t currentTime, const sp<Connection>& connection,
+            bool broken);
+    void drainOutboundQueueLocked(Connection* connection);
+    static int handleReceiveCallback(int receiveFd, int events, void* data);
+
+    // 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..903c3c4
--- /dev/null
+++ b/include/ui/InputReader.h
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UI_INPUT_READER_H
+#define _UI_INPUT_READER_H
+
+#include <ui/EventHub.h>
+#include <ui/Input.h>
+#include <ui/InputDispatcher.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+#include <utils/BitSet.h>
+
+#include <stddef.h>
+#include <unistd.h>
+
+namespace android {
+
+class InputDevice;
+class InputMapper;
+
+/* Describes a virtual key. */
+struct VirtualKeyDefinition {
+    int32_t scanCode;
+
+    // configured position data, specified in display coords
+    int32_t centerX;
+    int32_t centerY;
+    int32_t width;
+    int32_t height;
+};
+
+
+/* Specifies input device calibration settings. */
+class InputDeviceCalibration {
+public:
+    InputDeviceCalibration();
+
+    void clear();
+    void addProperty(const String8& key, const String8& value);
+
+    bool tryGetProperty(const String8& key, String8& outValue) const;
+    bool tryGetProperty(const String8& key, int32_t& outValue) const;
+    bool tryGetProperty(const String8& key, float& outValue) const;
+
+private:
+    KeyedVector<String8, String8> mProperties;
+};
+
+
+/*
+ * Input reader policy interface.
+ *
+ * The input reader policy is used by the input reader to interact with the Window Manager
+ * and other system components.
+ *
+ * The actual implementation is partially supported by callbacks into the DVM
+ * via JNI.  This interface is also mocked in the unit tests.
+ */
+class InputReaderPolicyInterface : public virtual RefBase {
+protected:
+    InputReaderPolicyInterface() { }
+    virtual ~InputReaderPolicyInterface() { }
+
+public:
+    /* Display orientations. */
+    enum {
+        ROTATION_0 = 0,
+        ROTATION_90 = 1,
+        ROTATION_180 = 2,
+        ROTATION_270 = 3
+    };
+
+    /* Actions returned by interceptXXX methods. */
+    enum {
+        // The input dispatcher should do nothing and discard the input unless other
+        // flags are set.
+        ACTION_NONE = 0,
+
+        // The input dispatcher should dispatch the input to the application.
+        ACTION_DISPATCH = 0x00000001,
+    };
+
+    /* Gets information about the display with the specified id.
+     * Returns true if the display info is available, false otherwise.
+     */
+    virtual bool getDisplayInfo(int32_t displayId,
+            int32_t* width, int32_t* height, int32_t* orientation) = 0;
+
+    /* Provides feedback for a virtual key down.
+     */
+    virtual void virtualKeyDownFeedback() = 0;
+
+    /* Intercepts a key event.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * Returns a policy action constant such as ACTION_DISPATCH.
+     */
+    virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
+            bool down, int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) = 0;
+
+    /* Intercepts a switch event.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * Switches are not dispatched to applications so this method should
+     * usually return ACTION_NONE.
+     */
+    virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
+            uint32_t& policyFlags) = 0;
+
+    /* Intercepts a generic touch, trackball or other event.
+     * The policy can use this method as an opportunity to perform power management functions
+     * and early event preprocessing such as updating policy flags.
+     *
+     * Returns a policy action constant such as ACTION_DISPATCH.
+     */
+    virtual int32_t interceptGeneric(nsecs_t when, uint32_t& policyFlags) = 0;
+
+    /* Determines whether to turn on some hacks we have to improve the touch interaction with a
+     * certain device whose screen currently is not all that good.
+     */
+    virtual bool filterTouchEvents() = 0;
+
+    /* Determines whether to turn on some hacks to improve touch interaction with another device
+     * where touch coordinate data can get corrupted.
+     */
+    virtual bool filterJumpyTouchEvents() = 0;
+
+    /* Gets the configured virtual key definitions for an input device. */
+    virtual void getVirtualKeyDefinitions(const String8& deviceName,
+            Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) = 0;
+
+    /* Gets the calibration for an input device. */
+    virtual void getInputDeviceCalibration(const String8& deviceName,
+            InputDeviceCalibration& outCalibration) = 0;
+
+    /* Gets the excluded device names for the platform. */
+    virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
+};
+
+
+/* Processes raw input events and sends cooked event data to an input dispatcher. */
+class InputReaderInterface : public virtual RefBase {
+protected:
+    InputReaderInterface() { }
+    virtual ~InputReaderInterface() { }
+
+public:
+    /* 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 {
+protected:
+    InputReaderContext() { }
+    virtual ~InputReaderContext() { }
+
+public:
+    virtual void updateGlobalMetaState() = 0;
+    virtual int32_t getGlobalMetaState() = 0;
+
+    virtual InputReaderPolicyInterface* getPolicy() = 0;
+    virtual InputDispatcherInterface* getDispatcher() = 0;
+    virtual EventHubInterface* getEventHub() = 0;
+};
+
+
+/* The input reader reads raw event data from the event hub and processes it into input events
+ * that it sends to the input dispatcher.  Some functions of the input reader, such as early
+ * event filtering in low power states, are controlled by a separate policy object.
+ *
+ * IMPORTANT INVARIANT:
+ *     Because the policy and dispatcher can potentially block or cause re-entrance into
+ *     the input reader, the input reader never calls into other components while holding
+ *     an exclusive internal lock whenever re-entrance can happen.
+ */
+class InputReader : public InputReaderInterface, private InputReaderContext {
+public:
+    InputReader(const sp<EventHubInterface>& eventHub,
+            const sp<InputReaderPolicyInterface>& policy,
+            const sp<InputDispatcherInterface>& dispatcher);
+    virtual ~InputReader();
+
+    virtual void 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);
+
+private:
+    sp<EventHubInterface> mEventHub;
+    sp<InputReaderPolicyInterface> mPolicy;
+    sp<InputDispatcherInterface> mDispatcher;
+
+    virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
+    virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
+    virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
+
+    // This reader/writer lock guards the list of input devices.
+    // The writer lock must be held whenever the list of input devices is modified
+    //   and then promptly released.
+    // The reader lock must be held whenever the list of input devices is traversed or an
+    //   input device in the list is accessed.
+    // This lock only protects the registry and prevents inadvertent deletion of device objects
+    // that are in use.  Individual devices are responsible for guarding their own internal state
+    // as needed for concurrent operation.
+    RWLock mDeviceRegistryLock;
+    KeyedVector<int32_t, InputDevice*> mDevices;
+
+    // low-level input event decoding and device management
+    void process(const RawEvent* rawEvent);
+
+    void addDevice(nsecs_t when, int32_t deviceId);
+    void removeDevice(nsecs_t when, int32_t deviceId);
+    InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes);
+    void configureExcludedDevices();
+
+    void consumeEvent(const RawEvent* rawEvent);
+
+    void handleConfigurationChanged(nsecs_t when);
+
+    // state management for all devices
+    Mutex mStateLock;
+
+    int32_t mGlobalMetaState;
+    virtual void updateGlobalMetaState();
+    virtual int32_t getGlobalMetaState();
+
+    InputConfiguration mInputConfiguration;
+    void updateInputConfiguration();
+
+    // state queries
+    typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+    int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+            GetStateFunc getStateFunc);
+    bool markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    // dump state
+    void dumpDeviceInfo(String8& dump);
+};
+
+
+/* Reads raw events from the event hub and processes them, endlessly. */
+class InputReaderThread : public Thread {
+public:
+    InputReaderThread(const sp<InputReaderInterface>& reader);
+    virtual ~InputReaderThread();
+
+private:
+    sp<InputReaderInterface> mReader;
+
+    virtual bool threadLoop();
+};
+
+
+/* Represents the state of a single input device. */
+class InputDevice {
+public:
+    InputDevice(InputReaderContext* context, int32_t id, const String8& name);
+    ~InputDevice();
+
+    inline InputReaderContext* getContext() { return mContext; }
+    inline int32_t getId() { return mId; }
+    inline const String8& getName() { return mName; }
+    inline uint32_t getSources() { return mSources; }
+
+    inline bool isIgnored() { return mMappers.isEmpty(); }
+
+    void addMapper(InputMapper* mapper);
+    void configure();
+    void reset();
+    void process(const RawEvent* rawEvent);
+
+    void getDeviceInfo(InputDeviceInfo* outDeviceInfo);
+    int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+    bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    int32_t getMetaState();
+
+    inline const InputDeviceCalibration& getCalibration() {
+        return mCalibration;
+    }
+
+private:
+    InputReaderContext* mContext;
+    int32_t mId;
+
+    Vector<InputMapper*> mMappers;
+
+    String8 mName;
+    uint32_t mSources;
+
+    typedef int32_t (InputMapper::*GetStateFunc)(uint32_t sourceMask, int32_t code);
+    int32_t getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc);
+
+    InputDeviceCalibration mCalibration;
+};
+
+
+/* An input mapper transforms raw input events into cooked event data.
+ * A single input device can have multiple associated input mappers in order to interpret
+ * different classes of events.
+ */
+class InputMapper {
+public:
+    InputMapper(InputDevice* device);
+    virtual ~InputMapper();
+
+    inline InputDevice* getDevice() { return mDevice; }
+    inline int32_t getDeviceId() { return mDevice->getId(); }
+    inline const String8 getDeviceName() { return mDevice->getName(); }
+    inline InputReaderContext* getContext() { return mContext; }
+    inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
+    inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
+    inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
+
+    virtual uint32_t getSources() = 0;
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void configure();
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent) = 0;
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    virtual int32_t getMetaState();
+
+protected:
+    InputDevice* mDevice;
+    InputReaderContext* mContext;
+
+    bool applyStandardPolicyActions(nsecs_t when, int32_t policyActions);
+};
+
+
+class SwitchInputMapper : public InputMapper {
+public:
+    SwitchInputMapper(InputDevice* device);
+    virtual ~SwitchInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getSwitchState(uint32_t sourceMask, int32_t switchCode);
+
+private:
+    void processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue);
+};
+
+
+class KeyboardInputMapper : public InputMapper {
+public:
+    KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId, uint32_t sources,
+            int32_t keyboardType);
+    virtual ~KeyboardInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+    virtual int32_t getMetaState();
+
+private:
+    Mutex mLock;
+
+    struct KeyDown {
+        int32_t keyCode;
+        int32_t scanCode;
+    };
+
+    int32_t mAssociatedDisplayId;
+    uint32_t mSources;
+    int32_t mKeyboardType;
+
+    struct LockedState {
+        Vector<KeyDown> keyDowns; // keys that are down
+        int32_t metaState;
+        nsecs_t downTime; // time of most recent key down
+    } mLocked;
+
+    void initializeLocked();
+
+    bool isKeyboardOrGamepadKey(int32_t scanCode);
+
+    void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode,
+            uint32_t policyFlags);
+    void applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags,
+            bool down, int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime);
+
+    ssize_t findKeyDownLocked(int32_t scanCode);
+};
+
+
+class TrackballInputMapper : public InputMapper {
+public:
+    TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~TrackballInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+
+private:
+    // Amount that trackball needs to move in order to generate a key event.
+    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
+
+    Mutex mLock;
+
+    int32_t mAssociatedDisplayId;
+
+    struct Accumulator {
+        enum {
+            FIELD_BTN_MOUSE = 1,
+            FIELD_REL_X = 2,
+            FIELD_REL_Y = 4
+        };
+
+        uint32_t fields;
+
+        bool btnMouse;
+        int32_t relX;
+        int32_t relY;
+
+        inline void clear() {
+            fields = 0;
+        }
+    } mAccumulator;
+
+    float mXScale;
+    float mYScale;
+    float mXPrecision;
+    float mYPrecision;
+
+    struct LockedState {
+        bool down;
+        nsecs_t downTime;
+    } mLocked;
+
+    void initializeLocked();
+
+    void sync(nsecs_t when);
+    void applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+            PointerCoords* pointerCoords, nsecs_t downTime);
+};
+
+
+class TouchInputMapper : public InputMapper {
+public:
+    TouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~TouchInputMapper();
+
+    virtual uint32_t getSources();
+    virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
+    virtual void configure();
+    virtual void reset();
+
+    virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
+    virtual int32_t getScanCodeState(uint32_t sourceMask, int32_t scanCode);
+    virtual bool markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+            const int32_t* keyCodes, uint8_t* outFlags);
+
+protected:
+    /* Maximum pointer id value supported.
+     * (This is limited by our use of BitSet32 to track pointer assignments.) */
+    static const uint32_t MAX_POINTER_ID = 31;
+
+    Mutex mLock;
+
+    struct VirtualKey {
+        int32_t keyCode;
+        int32_t scanCode;
+        uint32_t flags;
+
+        // computed hit box, specified in touch screen coords based on known display size
+        int32_t hitLeft;
+        int32_t hitTop;
+        int32_t hitRight;
+        int32_t hitBottom;
+
+        inline bool isHit(int32_t x, int32_t y) const {
+            return x >= hitLeft && x <= hitRight && y >= hitTop && y <= hitBottom;
+        }
+    };
+
+    // Raw data for a single pointer.
+    struct PointerData {
+        uint32_t id;
+        int32_t x;
+        int32_t y;
+        int32_t pressure;
+        int32_t touchMajor;
+        int32_t touchMinor;
+        int32_t toolMajor;
+        int32_t toolMinor;
+        int32_t orientation;
+    };
+
+    // Raw data for a collection of pointers including a pointer id mapping table.
+    struct TouchData {
+        uint32_t pointerCount;
+        PointerData pointers[MAX_POINTERS];
+        BitSet32 idBits;
+        uint32_t idToIndex[MAX_POINTER_ID + 1];
+
+        void copyFrom(const TouchData& other) {
+            pointerCount = other.pointerCount;
+            idBits = other.idBits;
+
+            for (uint32_t i = 0; i < pointerCount; i++) {
+                pointers[i] = other.pointers[i];
+
+                int id = pointers[i].id;
+                idToIndex[id] = other.idToIndex[id];
+            }
+        }
+
+        inline void clear() {
+            pointerCount = 0;
+            idBits.clear();
+        }
+    };
+
+    int32_t mAssociatedDisplayId;
+
+    // Immutable configuration parameters.
+    struct Parameters {
+        bool useBadTouchFilter;
+        bool useJumpyTouchFilter;
+        bool useAveragingTouchFilter;
+    } mParameters;
+
+    // Immutable calibration parameters in parsed form.
+    struct Calibration {
+        // Touch Area
+        enum TouchAreaCalibration {
+            TOUCH_AREA_CALIBRATION_DEFAULT,
+            TOUCH_AREA_CALIBRATION_NONE,
+            TOUCH_AREA_CALIBRATION_GEOMETRIC,
+            TOUCH_AREA_CALIBRATION_PRESSURE,
+        };
+
+        TouchAreaCalibration touchAreaCalibration;
+
+        // Tool Area
+        enum ToolAreaCalibration {
+            TOOL_AREA_CALIBRATION_DEFAULT,
+            TOOL_AREA_CALIBRATION_NONE,
+            TOOL_AREA_CALIBRATION_GEOMETRIC,
+            TOOL_AREA_CALIBRATION_LINEAR,
+        };
+
+        ToolAreaCalibration toolAreaCalibration;
+        bool haveToolAreaLinearScale;
+        float toolAreaLinearScale;
+        bool haveToolAreaLinearBias;
+        float toolAreaLinearBias;
+        bool haveToolAreaIsSummed;
+        int32_t toolAreaIsSummed;
+
+        // Pressure
+        enum PressureCalibration {
+            PRESSURE_CALIBRATION_DEFAULT,
+            PRESSURE_CALIBRATION_NONE,
+            PRESSURE_CALIBRATION_PHYSICAL,
+            PRESSURE_CALIBRATION_AMPLITUDE,
+        };
+        enum PressureSource {
+            PRESSURE_SOURCE_DEFAULT,
+            PRESSURE_SOURCE_PRESSURE,
+            PRESSURE_SOURCE_TOUCH,
+        };
+
+        PressureCalibration pressureCalibration;
+        PressureSource pressureSource;
+        bool havePressureScale;
+        float pressureScale;
+
+        // Size
+        enum SizeCalibration {
+            SIZE_CALIBRATION_DEFAULT,
+            SIZE_CALIBRATION_NONE,
+            SIZE_CALIBRATION_NORMALIZED,
+        };
+
+        SizeCalibration sizeCalibration;
+
+        // Orientation
+        enum OrientationCalibration {
+            ORIENTATION_CALIBRATION_DEFAULT,
+            ORIENTATION_CALIBRATION_NONE,
+            ORIENTATION_CALIBRATION_INTERPOLATED,
+        };
+
+        OrientationCalibration orientationCalibration;
+    } mCalibration;
+
+    // Raw axis information from the driver.
+    struct RawAxes {
+        RawAbsoluteAxisInfo x;
+        RawAbsoluteAxisInfo y;
+        RawAbsoluteAxisInfo pressure;
+        RawAbsoluteAxisInfo touchMajor;
+        RawAbsoluteAxisInfo touchMinor;
+        RawAbsoluteAxisInfo toolMajor;
+        RawAbsoluteAxisInfo toolMinor;
+        RawAbsoluteAxisInfo orientation;
+    } mRawAxes;
+
+    // Current and previous touch sample data.
+    TouchData mCurrentTouch;
+    TouchData mLastTouch;
+
+    // The time the primary pointer last went down.
+    nsecs_t mDownTime;
+
+    struct LockedState {
+        Vector<VirtualKey> virtualKeys;
+
+        // The surface orientation and width and height set by configureSurfaceLocked().
+        int32_t surfaceOrientation;
+        int32_t surfaceWidth, surfaceHeight;
+
+        // Translation and scaling factors, orientation-independent.
+        int32_t xOrigin;
+        float xScale;
+        float xPrecision;
+
+        int32_t yOrigin;
+        float yScale;
+        float yPrecision;
+
+        float geometricScale;
+
+        float toolAreaLinearScale;
+        float toolAreaLinearBias;
+
+        float pressureScale;
+
+        float sizeScale;
+
+        float orientationScale;
+
+        // Oriented motion ranges for input device info.
+        struct OrientedRanges {
+            InputDeviceInfo::MotionRange x;
+            InputDeviceInfo::MotionRange y;
+
+            bool havePressure;
+            InputDeviceInfo::MotionRange pressure;
+
+            bool haveSize;
+            InputDeviceInfo::MotionRange size;
+
+            bool haveTouchArea;
+            InputDeviceInfo::MotionRange touchMajor;
+            InputDeviceInfo::MotionRange touchMinor;
+
+            bool haveToolArea;
+            InputDeviceInfo::MotionRange toolMajor;
+            InputDeviceInfo::MotionRange toolMinor;
+
+            bool haveOrientation;
+            InputDeviceInfo::MotionRange orientation;
+        } orientedRanges;
+
+        // Oriented dimensions and precision.
+        float orientedSurfaceWidth, orientedSurfaceHeight;
+        float orientedXPrecision, orientedYPrecision;
+
+        struct CurrentVirtualKeyState {
+            bool down;
+            nsecs_t downTime;
+            int32_t keyCode;
+            int32_t scanCode;
+        } currentVirtualKey;
+    } mLocked;
+
+    virtual void configureParameters();
+    virtual void logParameters();
+    virtual void configureRawAxes();
+    virtual void logRawAxes();
+    virtual bool configureSurfaceLocked();
+    virtual void logMotionRangesLocked();
+    virtual void configureVirtualKeysLocked();
+    virtual void parseCalibration();
+    virtual void resolveCalibration();
+    virtual void logCalibration();
+
+    enum TouchResult {
+        // Dispatch the touch normally.
+        DISPATCH_TOUCH,
+        // Do not dispatch the touch, but keep tracking the current stroke.
+        SKIP_TOUCH,
+        // Do not dispatch the touch, and drop all information associated with the current stoke
+        // so the next movement will appear as a new down.
+        DROP_STROKE
+    };
+
+    void syncTouch(nsecs_t when, bool havePointerIds);
+
+private:
+    /* Maximum number of historical samples to average. */
+    static const uint32_t AVERAGING_HISTORY_SIZE = 5;
+
+    /* Slop distance for jumpy pointer detection.
+     * The vertical range of the screen divided by this is our epsilon value. */
+    static const uint32_t JUMPY_EPSILON_DIVISOR = 212;
+
+    /* Number of jumpy points to drop for touchscreens that need it. */
+    static const uint32_t JUMPY_TRANSITION_DROPS = 3;
+    static const uint32_t JUMPY_DROP_LIMIT = 3;
+
+    /* Maximum squared distance for averaging.
+     * If moving farther than this, turn of averaging to avoid lag in response. */
+    static const uint64_t AVERAGING_DISTANCE_LIMIT = 75 * 75;
+
+    struct AveragingTouchFilterState {
+        // Individual history tracks are stored by pointer id
+        uint32_t historyStart[MAX_POINTERS];
+        uint32_t historyEnd[MAX_POINTERS];
+        struct {
+            struct {
+                int32_t x;
+                int32_t y;
+                int32_t pressure;
+            } pointers[MAX_POINTERS];
+        } historyData[AVERAGING_HISTORY_SIZE];
+    } mAveragingTouchFilter;
+
+    struct JumpyTouchFilterState {
+        uint32_t jumpyPointsDropped;
+    } mJumpyTouchFilter;
+
+    struct PointerDistanceHeapElement {
+        uint32_t currentPointerIndex : 8;
+        uint32_t lastPointerIndex : 8;
+        uint64_t distance : 48; // squared distance
+    };
+
+    void initializeLocked();
+
+    TouchResult consumeOffScreenTouches(nsecs_t when, uint32_t policyFlags);
+    void dispatchTouches(nsecs_t when, uint32_t policyFlags);
+    void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
+            BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
+            int32_t motionEventAction);
+
+    void applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+            int32_t keyEventAction, int32_t keyEventFlags,
+            int32_t keyCode, int32_t scanCode, nsecs_t downTime);
+
+    bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
+    const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
+
+    bool applyBadTouchFilter();
+    bool applyJumpyTouchFilter();
+    void applyAveragingTouchFilter();
+    void calculatePointerIds();
+};
+
+
+class SingleTouchInputMapper : public TouchInputMapper {
+public:
+    SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~SingleTouchInputMapper();
+
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+protected:
+    virtual void configureRawAxes();
+
+private:
+    struct Accumulator {
+        enum {
+            FIELD_BTN_TOUCH = 1,
+            FIELD_ABS_X = 2,
+            FIELD_ABS_Y = 4,
+            FIELD_ABS_PRESSURE = 8,
+            FIELD_ABS_TOOL_WIDTH = 16
+        };
+
+        uint32_t fields;
+
+        bool btnTouch;
+        int32_t absX;
+        int32_t absY;
+        int32_t absPressure;
+        int32_t absToolWidth;
+
+        inline void clear() {
+            fields = 0;
+        }
+    } mAccumulator;
+
+    bool mDown;
+    int32_t mX;
+    int32_t mY;
+    int32_t mPressure;
+    int32_t mToolWidth;
+
+    void initialize();
+
+    void sync(nsecs_t when);
+};
+
+
+class MultiTouchInputMapper : public TouchInputMapper {
+public:
+    MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId);
+    virtual ~MultiTouchInputMapper();
+
+    virtual void reset();
+    virtual void process(const RawEvent* rawEvent);
+
+protected:
+    virtual void configureRawAxes();
+
+private:
+    struct Accumulator {
+        enum {
+            FIELD_ABS_MT_POSITION_X = 1,
+            FIELD_ABS_MT_POSITION_Y = 2,
+            FIELD_ABS_MT_TOUCH_MAJOR = 4,
+            FIELD_ABS_MT_TOUCH_MINOR = 8,
+            FIELD_ABS_MT_WIDTH_MAJOR = 16,
+            FIELD_ABS_MT_WIDTH_MINOR = 32,
+            FIELD_ABS_MT_ORIENTATION = 64,
+            FIELD_ABS_MT_TRACKING_ID = 128,
+            FIELD_ABS_MT_PRESSURE = 256,
+        };
+
+        uint32_t pointerCount;
+        struct Pointer {
+            uint32_t fields;
+
+            int32_t absMTPositionX;
+            int32_t absMTPositionY;
+            int32_t absMTTouchMajor;
+            int32_t absMTTouchMinor;
+            int32_t absMTWidthMajor;
+            int32_t absMTWidthMinor;
+            int32_t absMTOrientation;
+            int32_t absMTTrackingId;
+            int32_t absMTPressure;
+
+            inline void clear() {
+                fields = 0;
+            }
+        } pointers[MAX_POINTERS + 1]; // + 1 to remove the need for extra range checks
+
+        inline void clear() {
+            pointerCount = 0;
+            pointers[0].clear();
+        }
+    } mAccumulator;
+
+    void initialize();
+
+    void sync(nsecs_t when);
+};
+
+} // namespace android
+
+#endif // _UI_INPUT_READER_H
diff --git a/include/ui/InputTransport.h b/include/ui/InputTransport.h
new file mode 100644
index 0000000..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..c8d6ffc
--- 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,32 @@
     { "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;
-
 static const KeycodeLabel FLAGS[] = {
     { "WAKE", 0x00000001 },
     { "WAKE_DROPPED", 0x00000002 },
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..d59d72b 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -22,6 +22,8 @@
 
 #include <hardware/gralloc.h>
 
+#include <android/native_window.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -41,6 +43,14 @@
 
 struct android_native_buffer_t;
 
+typedef struct android_native_rect_t
+{
+    int32_t left;
+    int32_t top;
+    int32_t right;
+    int32_t bottom;
+} android_native_rect_t;
+
 // ---------------------------------------------------------------------------
 
 typedef struct android_native_base_t
@@ -63,15 +73,19 @@
 /* attributes queriable with query() */
 enum {
     NATIVE_WINDOW_WIDTH     = 0,
-    NATIVE_WINDOW_HEIGHT    = 1,
-    NATIVE_WINDOW_FORMAT    = 2,
+    NATIVE_WINDOW_HEIGHT,
+    NATIVE_WINDOW_FORMAT,
 };
 
 /* valid operations for the (*perform)() hook */
 enum {
     NATIVE_WINDOW_SET_USAGE  = 0,
-    NATIVE_WINDOW_CONNECT    = 1,
-    NATIVE_WINDOW_DISCONNECT = 2
+    NATIVE_WINDOW_CONNECT,
+    NATIVE_WINDOW_DISCONNECT,
+    NATIVE_WINDOW_SET_CROP,
+    NATIVE_WINDOW_SET_BUFFER_COUNT,
+    NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+    NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
 };
 
 /* parameter for NATIVE_WINDOW_[DIS]CONNECT */
@@ -79,16 +93,39 @@
     NATIVE_WINDOW_API_EGL = 1
 };
 
-typedef struct android_native_window_t 
+/* parameter for NATIVE_WINDOW_SET_BUFFERS_TRANSFORM */
+enum {
+    /* flip source image horizontally */
+    NATIVE_WINDOW_TRANSFORM_FLIP_H = HAL_TRANSFORM_FLIP_H ,
+    /* flip source image vertically */
+    NATIVE_WINDOW_TRANSFORM_FLIP_V = HAL_TRANSFORM_FLIP_V,
+    /* rotate source image 90 degrees clock-wise */
+    NATIVE_WINDOW_TRANSFORM_ROT_90 = HAL_TRANSFORM_ROT_90,
+    /* rotate source image 180 degrees */
+    NATIVE_WINDOW_TRANSFORM_ROT_180 = HAL_TRANSFORM_ROT_180,
+    /* rotate source image 270 degrees clock-wise */
+    NATIVE_WINDOW_TRANSFORM_ROT_270 = HAL_TRANSFORM_ROT_270,
+};
+
+struct ANativeWindow 
 {
 #ifdef __cplusplus
-    android_native_window_t()
+    ANativeWindow()
         : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
     {
         common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
-        common.version = sizeof(android_native_window_t);
+        common.version = sizeof(ANativeWindow);
         memset(common.reserved, 0, sizeof(common.reserved));
     }
+
+    // Implement the methods that sp<ANativeWindow> expects so that it
+    // can be used to automatically refcount ANativeWindow's.
+    void incStrong(const void* id) const {
+        common.incRef(const_cast<android_native_base_t*>(&common));
+    }
+    void decStrong(const void* id) const {
+        common.decRef(const_cast<android_native_base_t*>(&common));
+    }
 #endif
     
     struct android_native_base_t common;
@@ -115,7 +152,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*setSwapInterval)(struct android_native_window_t* window,
+    int     (*setSwapInterval)(struct ANativeWindow* window,
                 int interval);
     
     /*
@@ -125,7 +162,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*dequeueBuffer)(struct android_native_window_t* window, 
+    int     (*dequeueBuffer)(struct ANativeWindow* window,
                 struct android_native_buffer_t** buffer);
 
     /*
@@ -135,7 +172,7 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*lockBuffer)(struct android_native_window_t* window,
+    int     (*lockBuffer)(struct ANativeWindow* window,
                 struct android_native_buffer_t* buffer);
    /*
     * hook called by EGL when modifications to the render buffer are done. 
@@ -145,7 +182,7 @@
     * 
     * Returns 0 on success or -errno on error.
     */
-    int     (*queueBuffer)(struct android_native_window_t* window,
+    int     (*queueBuffer)(struct ANativeWindow* window,
                 struct android_native_buffer_t* buffer);
 
     /*
@@ -153,13 +190,13 @@
      * 
      * Returns 0 on success or -errno on error.
      */
-    int     (*query)(struct android_native_window_t* window,
+    int     (*query)(struct ANativeWindow* window,
                 int what, int* value);
     
     /*
      * hook used to perform various operations on the surface.
      * (*perform)() is a generic mechanism to add functionality to
-     * android_native_window_t while keeping backward binary compatibility.
+     * ANativeWindow while keeping backward binary compatibility.
      * 
      * This hook should not be called directly, instead use the helper functions
      * defined below.
@@ -171,19 +208,26 @@
      *     NATIVE_WINDOW_SET_USAGE
      *     NATIVE_WINDOW_CONNECT
      *     NATIVE_WINDOW_DISCONNECT
+     *     NATIVE_WINDOW_SET_CROP
+     *     NATIVE_WINDOW_SET_BUFFER_COUNT
+     *     NATIVE_WINDOW_SET_BUFFERS_GEOMETRY
+     *     NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
      *  
      */
     
-    int     (*perform)(struct android_native_window_t* window,
+    int     (*perform)(struct ANativeWindow* window,
                 int operation, ... );
     
     void* reserved_proc[3];
-} android_native_window_t;
+};
 
+// Backwards compatibility...  please switch to ANativeWindow.
+typedef struct ANativeWindow android_native_window_t;
 
 /*
- *  native_window_set_usage() sets the intended usage flags for the next
- *  buffers acquired with (*lockBuffer)() and on.
+ *  native_window_set_usage(..., usage)
+ *  Sets the intended usage flags for the next buffers
+ *  acquired with (*lockBuffer)() and on.
  *  By default (if this function is never called), a usage of
  *      GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE
  *  is assumed.
@@ -192,35 +236,96 @@
  */
 
 static inline int native_window_set_usage(
-        android_native_window_t* window, int usage)
+        ANativeWindow* window, int usage)
 {
     return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
 }
 
 /*
- * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made current.
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made current.
  * Returns -EINVAL if for some reason the window cannot be connected, which
  * can happen if it's connected to some other API.
  */
 static inline int native_window_connect(
-        android_native_window_t* window, int api)
+        ANativeWindow* window, int api)
 {
     return window->perform(window, NATIVE_WINDOW_CONNECT, api);
 }
 
 /*
- * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
- * by EGL when the window is made not current.
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL)
+ * Must be called by EGL when the window is made not current.
  * An error is returned if for instance the window wasn't connected in the
  * first place.
  */
 static inline int native_window_disconnect(
-        android_native_window_t* window, int api)
+        ANativeWindow* window, int api)
 {
     return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
 }
 
+/*
+ * native_window_set_crop(..., crop)
+ * Sets which region of the next queued buffers needs to be considered.
+ * A buffer's crop region is scaled to match the surface's size.
+ *
+ * The specified crop region applies to all buffers queued after it is called.
+ *
+ * if 'crop' is NULL, subsequently queued buffers won't be cropped.
+ *
+ * An error is returned if for instance the crop region is invalid,
+ * out of the buffer's bound or if the window is invalid.
+ */
+static inline int native_window_set_crop(
+        ANativeWindow* window,
+        android_native_rect_t const * crop)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_CROP, crop);
+}
+
+/*
+ * native_window_set_buffer_count(..., count)
+ * Sets the number of buffers associated with this native window.
+ */
+static inline int native_window_set_buffer_count(
+        ANativeWindow* window,
+        size_t bufferCount)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFER_COUNT, bufferCount);
+}
+
+/*
+ * native_window_set_buffers_geometry(..., int w, int h, int format)
+ * All buffers dequeued after this call will have the geometry specified.
+ * In particular, all buffers will have a fixed-size, independent form the
+ * native-window size. They will be appropriately scaled to the window-size
+ * upon composition.
+ *
+ * If all parameters are 0, the normal behavior is restored. That is,
+ * dequeued buffers following this call will be sized to the window's size.
+ *
+ */
+static inline int native_window_set_buffers_geometry(
+        ANativeWindow* window,
+        int w, int h, int format)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY,
+            w, h, format);
+}
+
+/*
+ * native_window_set_buffers_transform(..., int transform)
+ * All buffers queued after this call will be displayed transformed according
+ * to the transform parameter specified.
+ */
+static inline int native_window_set_buffers_transform(
+        ANativeWindow* window,
+        int transform)
+{
+    return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_TRANSFORM,
+            transform);
+}
 
 // ---------------------------------------------------------------------------
 
@@ -263,6 +368,15 @@
 template <typename NATIVE_TYPE, typename TYPE, typename REF>
 class EGLNativeBase : public NATIVE_TYPE, public REF
 {
+public:
+    // Disambiguate between the incStrong in REF and NATIVE_TYPE
+    void incStrong(const void* id) const {
+        REF::incStrong(id);
+    }
+    void decStrong(const void* id) const {
+        REF::decStrong(id);
+    }
+
 protected:
     typedef EGLNativeBase<NATIVE_TYPE, TYPE, REF> BASE;
     EGLNativeBase() : NATIVE_TYPE(), REF() {
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
index 5908bcc..2a09095 100644
--- a/include/utils/Asset.h
+++ b/include/utils/Asset.h
@@ -61,15 +61,6 @@
         ACCESS_BUFFER,
     } AccessMode;
 
-    enum {
-        /* data larger than this does not get uncompressed into a buffer */
-#ifdef HAVE_ANDROID_OS
-        UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
-#else
-        UNCOMPRESS_DATA_MAX = 2 * 1024 * 1024
-#endif
-    };
-
     /*
      * Read data from the current offset.  Returns the actual number of
      * bytes read, 0 on EOF, or -1 on error.
@@ -317,6 +308,8 @@
     FileMap*    mMap;           // for memory-mapped input
     int         mFd;            // for file input
 
+    class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets
+
     unsigned char*  mBuf;       // for getBuffer()
 };
 
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
index d8994e0..9e2bf37 100644
--- a/include/utils/AssetManager.h
+++ b/include/utils/AssetManager.h
@@ -29,6 +29,24 @@
 #include <utils/ZipFileRO.h>
 #include <utils/threads.h>
 
+/*
+ * Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct AAssetManager { };
+
+#ifdef __cplusplus
+};
+#endif
+
+
+/*
+ * Now the proper C++ android-namespace definitions
+ */
+
 namespace android {
 
 class Asset;        // fwd decl for things that include Asset.h first
@@ -48,7 +66,7 @@
  * The asset hierarchy may be examined like a filesystem, using
  * AssetDir objects to peruse a single directory.
  */
-class AssetManager {
+class AssetManager : public AAssetManager {
 public:
     typedef enum CacheMode {
         CACHE_UNKNOWN = 0,
@@ -111,6 +129,8 @@
      */
     void setConfiguration(const ResTable_config& config, const char* locale = NULL);
 
+    void getConfiguration(ResTable_config* outConfig) const;
+
     typedef Asset::AccessMode AccessMode;       // typing shortcut
 
     /*
diff --git a/include/utils/BitSet.h b/include/utils/BitSet.h
new file mode 100644
index 0000000..19c8bf0
--- /dev/null
+++ b/include/utils/BitSet.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_BITSET_H
+#define UTILS_BITSET_H
+
+#include <stdint.h>
+
+/*
+ * Contains some bit manipulation helpers.
+ */
+
+namespace android {
+
+// A simple set of 32 bits that can be individually marked or cleared.
+struct BitSet32 {
+    uint32_t value;
+
+    inline BitSet32() : value(0) { }
+    explicit inline BitSet32(uint32_t value) : value(value) { }
+
+    // Gets the value associated with a particular bit index.
+    static inline uint32_t valueForBit(uint32_t n) { return 0x80000000 >> n; }
+
+    // Clears the bit set.
+    inline void clear() { value = 0; }
+
+    // Returns true if the bit set does not contain any marked bits.
+    inline bool isEmpty() const { return ! value; }
+
+    // Returns true if the specified bit is marked.
+    inline bool hasBit(uint32_t n) const { return value & valueForBit(n); }
+
+    // Marks the specified bit.
+    inline void markBit(uint32_t n) { value |= valueForBit(n); }
+
+    // Clears the specified bit.
+    inline void clearBit(uint32_t n) { value &= ~ valueForBit(n); }
+
+    // Finds the first marked bit in the set.
+    // Result is undefined if all bits are unmarked.
+    inline uint32_t firstMarkedBit() const { return __builtin_clz(value); }
+
+    // Finds the first unmarked bit in the set.
+    // Result is undefined if all bits are marked.
+    inline uint32_t firstUnmarkedBit() const { return __builtin_clz(~ value); }
+
+    inline bool operator== (const BitSet32& other) const { return value == other.value; }
+    inline bool operator!= (const BitSet32& other) const { return value != other.value; }
+};
+
+} // namespace android
+
+#endif // UTILS_BITSET_H
diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h
deleted file mode 100644
index 8e22b0f..0000000
--- a/include/utils/Buffer.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __UTILS_BUFFER_H__
-#define __UTILS_BUFFER_H__ 1
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-namespace android {
-
-class Buffer
-{
-private:
-    char *buf;
-    int bufsiz;
-    int used;
-    void ensureCapacity(int len);
-
-    void
-    makeRoomFor(int len)
-    {
-        if (len + used >= bufsiz) {
-            bufsiz = (len + used) * 3/2 + 2;
-            char *blah = new char[bufsiz];
-
-            memcpy(blah, buf, used);
-            delete[] buf;
-            buf = blah;
-        }
-    }
-    
-public:
-    Buffer()
-    {
-        bufsiz = 16;
-        buf = new char[bufsiz];
-        clear();
-    }
-
-    ~Buffer()
-    {
-       delete[] buf;
-    }
-
-    void
-    clear()
-    {
-        buf[0] = '\0';
-        used = 0;
-    }
-
-    int
-    length()
-    {
-        return used;
-    }
-
-    void
-    append(const char c)
-    {
-        makeRoomFor(1);
-        buf[used] = c;
-        used++;
-        buf[used] = '\0';
-    }
-
-    void
-    append(const char *s, int len)
-    {
-        makeRoomFor(len);
-
-        memcpy(buf + used, s, len);
-        used += len;
-        buf[used] = '\0';
-    }
-
-    void
-    append(const char *s)
-    {
-        append(s, strlen(s));
-    }
-
-    char *
-    getBytes()
-    {
-        return buf;
-    }
-};
-
-}; // namespace android
-
-#endif
diff --git a/include/utils/Looper.h b/include/utils/Looper.h
new file mode 100644
index 0000000..3f00b78
--- /dev/null
+++ b/include/utils/Looper.h
@@ -0,0 +1,214 @@
+/*
+ * 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 <android/looper.h>
+
+/*
+ * 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 mEpollFd; // immutable
+    int mWakeReadPipeFd;  // immutable
+    int mWakeWritePipeFd; // immutable
+
+    // Locked list of file descriptor monitoring requests.
+    Mutex mLock;
+    KeyedVector<int, Request> mRequests;
+
+    // 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);
+
+    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..5243f50
--- /dev/null
+++ b/include/utils/ObbFile.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OBBFILE_H_
+#define OBBFILE_H_
+
+#include <stdint.h>
+#include <strings.h>
+
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+namespace android {
+
+// OBB flags (bit 0)
+#define OBB_OVERLAY         (1 << 0)
+
+class ObbFile : public RefBase {
+protected:
+    virtual ~ObbFile();
+
+public:
+    ObbFile();
+
+    bool readFrom(const char* filename);
+    bool readFrom(int fd);
+    bool writeTo(const char* filename);
+    bool writeTo(int fd);
+    bool removeFrom(const char* filename);
+    bool removeFrom(int fd);
+
+    const char* getFileName() const {
+        return mFileName;
+    }
+
+    const String8 getPackageName() const {
+        return mPackageName;
+    }
+
+    void setPackageName(String8 packageName) {
+        mPackageName = packageName;
+    }
+
+    int32_t getVersion() const {
+        return mVersion;
+    }
+
+    void setVersion(int32_t version) {
+        mVersion = version;
+    }
+
+    int32_t getFlags() const {
+        return mFlags;
+    }
+
+    void setFlags(int32_t flags) {
+        mFlags = flags;
+    }
+
+    bool isOverlay() {
+        return (mFlags & OBB_OVERLAY) == OBB_OVERLAY;
+    }
+
+    void setOverlay(bool overlay) {
+        if (overlay) {
+            mFlags |= OBB_OVERLAY;
+        } else {
+            mFlags &= ~OBB_OVERLAY;
+        }
+    }
+
+    static inline uint32_t get4LE(const unsigned char* buf) {
+        return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+    }
+
+    static inline void put4LE(unsigned char* buf, uint32_t val) {
+        buf[0] = val & 0xFF;
+        buf[1] = (val >> 8) & 0xFF;
+        buf[2] = (val >> 16) & 0xFF;
+        buf[3] = (val >> 24) & 0xFF;
+    }
+
+private:
+    /* Package name this ObbFile is associated with */
+    String8 mPackageName;
+
+    /* Package version this ObbFile is associated with */
+    int32_t mVersion;
+
+    /* Flags for this OBB type. */
+    int32_t mFlags;
+
+    const char* mFileName;
+
+    size_t mFileSize;
+
+    size_t mFooterStart;
+
+    unsigned char* mReadBuf;
+
+    bool parseObbFile(int fd);
+};
+
+}
+#endif /* OBBFILE_H_ */
diff --git a/include/utils/Pool.h b/include/utils/Pool.h
new file mode 100644
index 0000000..2ee768e
--- /dev/null
+++ b/include/utils/Pool.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef UTILS_POOL_H
+#define UTILS_POOL_H
+
+#include <utils/TypeHelpers.h>
+
+namespace android {
+
+class PoolImpl {
+public:
+    PoolImpl(size_t objSize);
+    ~PoolImpl();
+
+    void* allocImpl();
+    void freeImpl(void* obj);
+
+private:
+    size_t mObjSize;
+};
+
+/*
+ * A homogeneous typed memory pool for fixed size objects.
+ * Not intended to be thread-safe.
+ */
+template<typename T>
+class Pool : private PoolImpl {
+public:
+    /* Creates an initially empty pool. */
+    Pool() : PoolImpl(sizeof(T)) { }
+
+    /* Destroys the pool.
+     * Assumes that the pool is empty. */
+    ~Pool() { }
+
+    /* Allocates an object from the pool, growing the pool if needed. */
+    inline T* alloc() {
+        void* mem = allocImpl();
+        if (! traits<T>::has_trivial_ctor) {
+            return new (mem) T();
+        } else {
+            return static_cast<T*>(mem);
+        }
+    }
+
+    /* Frees an object from the pool. */
+    inline void free(T* obj) {
+        if (! traits<T>::has_trivial_dtor) {
+            obj->~T();
+        }
+        freeImpl(obj);
+    }
+};
+
+} // namespace android
+
+#endif // UTILS_POOL_H
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
index bd7f28c..9c64ac0 100644
--- a/include/utils/RefBase.h
+++ b/include/utils/RefBase.h
@@ -333,9 +333,10 @@
 
 template<typename T>
 sp<T>& sp<T>::operator = (const sp<T>& other) {
-    if (other.m_ptr) other.m_ptr->incStrong(this);
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
     if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other.m_ptr;
+    m_ptr = otherPtr;
     return *this;
 }
 
@@ -351,9 +352,10 @@
 template<typename T> template<typename U>
 sp<T>& sp<T>::operator = (const sp<U>& other)
 {
-    if (other.m_ptr) other.m_ptr->incStrong(this);
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherPtr->incStrong(this);
     if (m_ptr) m_ptr->decStrong(this);
-    m_ptr = other.m_ptr;
+    m_ptr = otherPtr;
     return *this;
 }
 
@@ -466,10 +468,12 @@
 template<typename T>
 wp<T>& wp<T>::operator = (const wp<T>& other)
 {
-    if (other.m_ptr) other.m_refs->incWeak(this);
+    weakref_type* otherRefs(other.m_refs);
+    T* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.m_ptr;
-    m_refs = other.m_refs;
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
     return *this;
 }
 
@@ -478,8 +482,9 @@
 {
     weakref_type* newRefs =
         other != NULL ? other->createWeak(this) : 0;
+    T* otherPtr(other.m_ptr);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.get();
+    m_ptr = otherPtr;
     m_refs = newRefs;
     return *this;
 }
@@ -498,10 +503,12 @@
 template<typename T> template<typename U>
 wp<T>& wp<T>::operator = (const wp<U>& other)
 {
-    if (other.m_ptr) other.m_refs->incWeak(this);
+    weakref_type* otherRefs(other.m_refs);
+    U* otherPtr(other.m_ptr);
+    if (otherPtr) otherRefs->incWeak(this);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.m_ptr;
-    m_refs = other.m_refs;
+    m_ptr = otherPtr;
+    m_refs = otherRefs;
     return *this;
 }
 
@@ -510,8 +517,9 @@
 {
     weakref_type* newRefs =
         other != NULL ? other->createWeak(this) : 0;
+    U* otherPtr(other.m_ptr);
     if (m_ptr) m_refs->decWeak(this);
-    m_ptr = other.get();
+    m_ptr = otherPtr;
     m_refs = newRefs;
     return *this;
 }
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index b701ce7..da86da4 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -31,6 +31,8 @@
 #include <stdint.h>
 #include <sys/types.h>
 
+#include <android/configuration.h>
+
 namespace android {
 
 /** ********************************************************************
@@ -822,25 +824,25 @@
     };
     
     enum {
-        ORIENTATION_ANY  = 0x0000,
-        ORIENTATION_PORT = 0x0001,
-        ORIENTATION_LAND = 0x0002,
-        ORIENTATION_SQUARE = 0x0003,
+        ORIENTATION_ANY  = ACONFIGURATION_ORIENTATION_ANY,
+        ORIENTATION_PORT = ACONFIGURATION_ORIENTATION_PORT,
+        ORIENTATION_LAND = ACONFIGURATION_ORIENTATION_LAND,
+        ORIENTATION_SQUARE = ACONFIGURATION_ORIENTATION_SQUARE,
     };
     
     enum {
-        TOUCHSCREEN_ANY  = 0x0000,
-        TOUCHSCREEN_NOTOUCH  = 0x0001,
-        TOUCHSCREEN_STYLUS  = 0x0002,
-        TOUCHSCREEN_FINGER  = 0x0003,
+        TOUCHSCREEN_ANY  = ACONFIGURATION_TOUCHSCREEN_ANY,
+        TOUCHSCREEN_NOTOUCH  = ACONFIGURATION_TOUCHSCREEN_NOTOUCH,
+        TOUCHSCREEN_STYLUS  = ACONFIGURATION_TOUCHSCREEN_STYLUS,
+        TOUCHSCREEN_FINGER  = ACONFIGURATION_TOUCHSCREEN_FINGER,
     };
     
     enum {
-        DENSITY_DEFAULT = 0,
-        DENSITY_LOW = 120,
-        DENSITY_MEDIUM = 160,
-        DENSITY_HIGH = 240,
-        DENSITY_NONE = 0xffff
+        DENSITY_DEFAULT = ACONFIGURATION_DENSITY_DEFAULT,
+        DENSITY_LOW = ACONFIGURATION_DENSITY_LOW,
+        DENSITY_MEDIUM = ACONFIGURATION_DENSITY_MEDIUM,
+        DENSITY_HIGH = ACONFIGURATION_DENSITY_HIGH,
+        DENSITY_NONE = ACONFIGURATION_DENSITY_NONE
     };
     
     union {
@@ -853,33 +855,34 @@
     };
     
     enum {
-        KEYBOARD_ANY  = 0x0000,
-        KEYBOARD_NOKEYS  = 0x0001,
-        KEYBOARD_QWERTY  = 0x0002,
-        KEYBOARD_12KEY  = 0x0003,
+        KEYBOARD_ANY  = ACONFIGURATION_KEYBOARD_ANY,
+        KEYBOARD_NOKEYS  = ACONFIGURATION_KEYBOARD_NOKEYS,
+        KEYBOARD_QWERTY  = ACONFIGURATION_KEYBOARD_QWERTY,
+        KEYBOARD_12KEY  = ACONFIGURATION_KEYBOARD_12KEY,
     };
     
     enum {
-        NAVIGATION_ANY  = 0x0000,
-        NAVIGATION_NONAV  = 0x0001,
-        NAVIGATION_DPAD  = 0x0002,
-        NAVIGATION_TRACKBALL  = 0x0003,
-        NAVIGATION_WHEEL  = 0x0004,
+        NAVIGATION_ANY  = ACONFIGURATION_NAVIGATION_ANY,
+        NAVIGATION_NONAV  = ACONFIGURATION_NAVIGATION_NONAV,
+        NAVIGATION_DPAD  = ACONFIGURATION_NAVIGATION_DPAD,
+        NAVIGATION_TRACKBALL  = ACONFIGURATION_NAVIGATION_TRACKBALL,
+        NAVIGATION_WHEEL  = ACONFIGURATION_NAVIGATION_WHEEL,
     };
     
     enum {
         MASK_KEYSHIDDEN = 0x0003,
-        KEYSHIDDEN_ANY = 0x0000,
-        KEYSHIDDEN_NO = 0x0001,
-        KEYSHIDDEN_YES = 0x0002,
-        KEYSHIDDEN_SOFT = 0x0003,
+        KEYSHIDDEN_ANY = ACONFIGURATION_KEYSHIDDEN_ANY,
+        KEYSHIDDEN_NO = ACONFIGURATION_KEYSHIDDEN_NO,
+        KEYSHIDDEN_YES = ACONFIGURATION_KEYSHIDDEN_YES,
+        KEYSHIDDEN_SOFT = ACONFIGURATION_KEYSHIDDEN_SOFT,
     };
     
     enum {
         MASK_NAVHIDDEN = 0x000c,
-        NAVHIDDEN_ANY = 0x0000,
-        NAVHIDDEN_NO = 0x0004,
-        NAVHIDDEN_YES = 0x0008,
+        SHIFT_NAVHIDDEN = 2,
+        NAVHIDDEN_ANY = ACONFIGURATION_NAVHIDDEN_ANY << SHIFT_NAVHIDDEN,
+        NAVHIDDEN_NO = ACONFIGURATION_NAVHIDDEN_NO << SHIFT_NAVHIDDEN,
+        NAVHIDDEN_YES = ACONFIGURATION_NAVHIDDEN_YES << SHIFT_NAVHIDDEN,
     };
     
     union {
@@ -929,31 +932,34 @@
     enum {
         // screenLayout bits for screen size class.
         MASK_SCREENSIZE = 0x0f,
-        SCREENSIZE_ANY  = 0x00,
-        SCREENSIZE_SMALL = 0x01,
-        SCREENSIZE_NORMAL = 0x02,
-        SCREENSIZE_LARGE = 0x03,
+        SCREENSIZE_ANY = ACONFIGURATION_SCREENSIZE_ANY,
+        SCREENSIZE_SMALL = ACONFIGURATION_SCREENSIZE_SMALL,
+        SCREENSIZE_NORMAL = ACONFIGURATION_SCREENSIZE_NORMAL,
+        SCREENSIZE_LARGE = ACONFIGURATION_SCREENSIZE_LARGE,
+        SCREENSIZE_XLARGE = ACONFIGURATION_SCREENSIZE_XLARGE,
         
         // screenLayout bits for wide/long screen variation.
         MASK_SCREENLONG = 0x30,
-        SCREENLONG_ANY = 0x00,
-        SCREENLONG_NO = 0x10,
-        SCREENLONG_YES = 0x20,
+        SHIFT_SCREENLONG = 4,
+        SCREENLONG_ANY = ACONFIGURATION_SCREENLONG_ANY << SHIFT_SCREENLONG,
+        SCREENLONG_NO = ACONFIGURATION_SCREENLONG_NO << SHIFT_SCREENLONG,
+        SCREENLONG_YES = ACONFIGURATION_SCREENLONG_YES << SHIFT_SCREENLONG,
     };
     
     enum {
         // uiMode bits for the mode type.
         MASK_UI_MODE_TYPE = 0x0f,
-        UI_MODE_TYPE_ANY = 0x00,
-        UI_MODE_TYPE_NORMAL = 0x01,
-        UI_MODE_TYPE_DESK = 0x02,
-        UI_MODE_TYPE_CAR = 0x03,
+        UI_MODE_TYPE_ANY = ACONFIGURATION_UI_MODE_TYPE_ANY,
+        UI_MODE_TYPE_NORMAL = ACONFIGURATION_UI_MODE_TYPE_NORMAL,
+        UI_MODE_TYPE_DESK = ACONFIGURATION_UI_MODE_TYPE_DESK,
+        UI_MODE_TYPE_CAR = ACONFIGURATION_UI_MODE_TYPE_CAR,
 
         // uiMode bits for the night switch.
         MASK_UI_MODE_NIGHT = 0x30,
-        UI_MODE_NIGHT_ANY = 0x00,
-        UI_MODE_NIGHT_NO = 0x10,
-        UI_MODE_NIGHT_YES = 0x20,
+        SHIFT_UI_MODE_NIGHT = 4,
+        UI_MODE_NIGHT_ANY = ACONFIGURATION_UI_MODE_NIGHT_ANY << SHIFT_UI_MODE_NIGHT,
+        UI_MODE_NIGHT_NO = ACONFIGURATION_UI_MODE_NIGHT_NO << SHIFT_UI_MODE_NIGHT,
+        UI_MODE_NIGHT_YES = ACONFIGURATION_UI_MODE_NIGHT_YES << SHIFT_UI_MODE_NIGHT,
     };
 
     union {
@@ -1022,19 +1028,19 @@
     // match the corresponding ones in android.content.pm.ActivityInfo and
     // attrs_manifest.xml.
     enum {
-        CONFIG_MCC = 0x0001,
-        CONFIG_MNC = 0x0002,
-        CONFIG_LOCALE = 0x0004,
-        CONFIG_TOUCHSCREEN = 0x0008,
-        CONFIG_KEYBOARD = 0x0010,
-        CONFIG_KEYBOARD_HIDDEN = 0x0020,
-        CONFIG_NAVIGATION = 0x0040,
-        CONFIG_ORIENTATION = 0x0080,
-        CONFIG_DENSITY = 0x0100,
-        CONFIG_SCREEN_SIZE = 0x0200,
-        CONFIG_VERSION = 0x0400,
-        CONFIG_SCREEN_LAYOUT = 0x0800,
-        CONFIG_UI_MODE = 0x1000
+        CONFIG_MCC = ACONFIGURATION_MCC,
+        CONFIG_MNC = ACONFIGURATION_MCC,
+        CONFIG_LOCALE = ACONFIGURATION_LOCALE,
+        CONFIG_TOUCHSCREEN = ACONFIGURATION_TOUCHSCREEN,
+        CONFIG_KEYBOARD = ACONFIGURATION_KEYBOARD,
+        CONFIG_KEYBOARD_HIDDEN = ACONFIGURATION_KEYBOARD_HIDDEN,
+        CONFIG_NAVIGATION = ACONFIGURATION_NAVIGATION,
+        CONFIG_ORIENTATION = ACONFIGURATION_ORIENTATION,
+        CONFIG_DENSITY = ACONFIGURATION_DENSITY,
+        CONFIG_SCREEN_SIZE = ACONFIGURATION_SCREEN_SIZE,
+        CONFIG_VERSION = ACONFIGURATION_VERSION,
+        CONFIG_SCREEN_LAYOUT = ACONFIGURATION_SCREEN_LAYOUT,
+        CONFIG_UI_MODE = ACONFIGURATION_UI_MODE
     };
     
     // Compare two configuration, returning CONFIG_* flags set for each value
@@ -1208,7 +1214,28 @@
             if (screenLayout || o.screenLayout) {
                 if (((screenLayout^o.screenLayout) & MASK_SCREENSIZE) != 0
                         && (requested->screenLayout & MASK_SCREENSIZE)) {
-                    return (screenLayout & MASK_SCREENSIZE);
+                    // A little backwards compatibility here: undefined is
+                    // considered equivalent to normal.  But only if the
+                    // requested size is at least normal; otherwise, small
+                    // is better than the default.
+                    int mySL = (screenLayout & MASK_SCREENSIZE);
+                    int oSL = (o.screenLayout & MASK_SCREENSIZE);
+                    int fixedMySL = mySL;
+                    int fixedOSL = oSL;
+                    if ((requested->screenLayout & MASK_SCREENSIZE) >= SCREENSIZE_NORMAL) {
+                        if (fixedMySL == 0) fixedMySL = SCREENSIZE_NORMAL;
+                        if (fixedOSL == 0) fixedOSL = SCREENSIZE_NORMAL;
+                    }
+                    // For screen size, the best match is the one that is
+                    // closest to the requested screen size, but not over
+                    // (the not over part is dealt with in match() below).
+                    if (fixedMySL == fixedOSL) {
+                        // If the two are the same, but 'this' is actually
+                        // undefined, then the other is really a better match.
+                        if (mySL == 0) return false;
+                        return true;
+                    }
+                    return fixedMySL >= fixedOSL;
                 }
                 if (((screenLayout^o.screenLayout) & MASK_SCREENLONG) != 0
                         && (requested->screenLayout & MASK_SCREENLONG)) {
@@ -1370,8 +1397,11 @@
         if (screenConfig != 0) {
             const int screenSize = screenLayout&MASK_SCREENSIZE;
             const int setScreenSize = settings.screenLayout&MASK_SCREENSIZE;
-            if (setScreenSize != 0 && screenSize != 0
-                    && screenSize != setScreenSize) {
+            // Any screen sizes for larger screens than the setting do not
+            // match.
+            if ((setScreenSize != 0 && screenSize != 0
+                    && screenSize > setScreenSize) ||
+                    (setScreenSize == 0 && screenSize != 0)) {
                 return false;
             }
             
diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h
index bc7626a..3b975b4 100644
--- a/include/utils/Singleton.h
+++ b/include/utils/Singleton.h
@@ -54,11 +54,13 @@
  * (eg: <TYPE>.cpp) to create the static instance of Singleton<>'s attributes,
  * and avoid to have a copy of them in each compilation units Singleton<TYPE>
  * is used.
+ * NOTE: we use a version of Mutex ctor that takes a parameter, because
+ * for some unknown reason using the default ctor doesn't emit the variable!
  */
 
-#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)             \
-    template class Singleton< TYPE >;                       \
-    template< class TYPE > Mutex Singleton< TYPE >::sLock;  \
+#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE)                 \
+    template class Singleton< TYPE >;                           \
+    template<> Mutex Singleton< TYPE >::sLock(Mutex::PRIVATE);  \
     template<> TYPE* Singleton< TYPE >::sInstance(0);
 
 
diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h
index cc0bebc..693dd3c 100644
--- a/include/utils/StopWatch.h
+++ b/include/utils/StopWatch.h
@@ -37,6 +37,8 @@
         const char* name() const;
         nsecs_t     lap();
         nsecs_t     elapsedTime() const;
+
+        void        reset();
         
 private:
     const char*     mName;
diff --git a/include/utils/StreamingZipInflater.h b/include/utils/StreamingZipInflater.h
new file mode 100644
index 0000000..16867d8
--- /dev/null
+++ b/include/utils/StreamingZipInflater.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __LIBS_STREAMINGZIPINFLATER_H
+#define __LIBS_STREAMINGZIPINFLATER_H
+
+#include <unistd.h>
+#include <inttypes.h>
+#include <zlib.h>
+
+namespace android {
+
+class StreamingZipInflater {
+public:
+    static const size_t INPUT_CHUNK_SIZE = 64 * 1024;
+    static const size_t OUTPUT_CHUNK_SIZE = 64 * 1024;
+
+    // Flavor that pages in the compressed data from a fd
+    StreamingZipInflater(int fd, off_t compDataStart, size_t uncompSize, size_t compSize);
+
+    // Flavor that gets the compressed data from an in-memory buffer
+    StreamingZipInflater(class FileMap* dataMap, size_t uncompSize);
+
+    ~StreamingZipInflater();
+
+    // read 'count' bytes of uncompressed data from the current position.  outBuf may
+    // be NULL, in which case the data is consumed and discarded.
+    ssize_t read(void* outBuf, size_t count);
+
+    // seeking backwards requires uncompressing fom the beginning, so is very
+    // expensive.  seeking forwards only requires uncompressing from the current
+    // position to the destination.
+    off_t seekAbsolute(off_t absoluteInputPosition);
+
+private:
+    void initInflateState();
+    int readNextChunk();
+
+    // where to find the uncompressed data
+    int mFd;
+    off_t mInFileStart;         // where the compressed data lives in the file
+    class FileMap* mDataMap;
+
+    z_stream mInflateState;
+    bool mStreamNeedsInit;
+
+    // output invariants for this asset
+    uint8_t* mOutBuf;           // output buf for decompressed bytes
+    size_t mOutBufSize;         // allocated size of mOutBuf
+    size_t mOutTotalSize;       // total uncompressed size of the blob
+
+    // current output state bookkeeping
+    off_t mOutCurPosition;      // current position in total offset
+    size_t mOutLastDecoded;     // last decoded byte + 1 in mOutbuf
+    size_t mOutDeliverable;     // next undelivered byte of decoded output in mOutBuf
+
+    // input invariants
+    uint8_t* mInBuf;
+    size_t mInBufSize;          // allocated size of mInBuf;
+    size_t mInTotalSize;        // total size of compressed data for this blob
+
+    // input state bookkeeping
+    size_t mInNextChunkOffset;  // offset from start of blob at which the next input chunk lies
+    // the z_stream contains state about input block consumption
+};
+
+}
+
+#endif
diff --git a/include/utils/String8.h b/include/utils/String8.h
index c4b18a4..ef0b51a 100644
--- a/include/utils/String8.h
+++ b/include/utils/String8.h
@@ -171,6 +171,9 @@
             status_t            append(const char* other);
             status_t            append(const char* other, size_t numChars);
 
+            status_t            appendFormat(const char* fmt, ...)
+                    __attribute__((format (printf, 2, 3)));
+
             // Note that this function takes O(N) time to calculate the value.
             // No cache value is stored.
             size_t              getUtf32Length() const;
@@ -372,7 +375,7 @@
 
 inline String8 String8::operator+(const String8& other) const
 {
-    String8 tmp;
+    String8 tmp(*this);
     tmp += other;
     return tmp;
 }
@@ -385,7 +388,7 @@
 
 inline String8 String8::operator+(const char* other) const
 {
-    String8 tmp;
+    String8 tmp(*this);
     tmp += other;
     return tmp;
 }
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
index ad59fd6..ec851bd 100644
--- a/include/utils/Vector.h
+++ b/include/utils/Vector.h
@@ -114,13 +114,19 @@
             ssize_t         appendVector(const Vector<TYPE>& vector);
 
 
+    //! insert an array at a given index
+            ssize_t         insertArrayAt(const TYPE* array, size_t index, size_t length);
+
+    //! append an array at the end of this vector
+            ssize_t         appendArray(const TYPE* array, size_t length);
+
             /*! 
              * add/insert/replace items
              */
              
     //! insert one or several items initialized with their default constructor
     inline  ssize_t         insertAt(size_t index, size_t numItems = 1);
-    //! insert on onr several items initialized from a prototype item
+    //! insert one or several items initialized from a prototype item
             ssize_t         insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
     //! pop the top of the stack (removes the last element). No-op if the stack's empty
     inline  void            pop();
@@ -259,6 +265,16 @@
 }
 
 template<class TYPE> inline
+ssize_t Vector<TYPE>::insertArrayAt(const TYPE* array, size_t index, size_t length) {
+    return VectorImpl::insertArrayAt(array, index, length);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::appendArray(const TYPE* array, size_t length) {
+    return VectorImpl::appendArray(array, length);
+}
+
+template<class TYPE> inline
 ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
     return VectorImpl::insertAt(&item, index, numItems);
 }
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
index 49b03f1..c4ec2ff 100644
--- a/include/utils/VectorImpl.h
+++ b/include/utils/VectorImpl.h
@@ -65,9 +65,11 @@
             size_t          capacity() const;
             ssize_t         setCapacity(size_t size);
 
-            /*! append/insert another vector */
+            /*! append/insert another vector or array */
             ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
             ssize_t         appendVector(const VectorImpl& vector);
+            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);
+            ssize_t         appendArray(const void* array, size_t length);
             
             /*! add/insert/replace items */
             ssize_t         insertAt(size_t where, size_t numItems = 1);
@@ -184,6 +186,8 @@
             void            push(const void* item);
             ssize_t         insertVectorAt(const VectorImpl& vector, size_t index);
             ssize_t         appendVector(const VectorImpl& vector);
+            ssize_t         insertArrayAt(const void* array, size_t index, size_t length);
+            ssize_t         appendArray(const void* array, size_t length);
             ssize_t         insertAt(size_t where, size_t numItems = 1);
             ssize_t         insertAt(const void* item, size_t where, size_t numItems = 1);
             ssize_t         replaceAt(size_t index);
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
index 30e0036..e38bf66 100644
--- a/include/utils/ZipFileCRO.h
+++ b/include/utils/ZipFileCRO.h
@@ -47,8 +47,8 @@
         const char* fileName);
 
 extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
-        int* pMethod, long* pUncompLen,
-        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+        int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
 
 extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
 
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
index 51c4f2f..97d31f4 100644
--- a/include/utils/ZipFileRO.h
+++ b/include/utils/ZipFileRO.h
@@ -58,14 +58,19 @@
 class ZipFileRO {
 public:
     ZipFileRO()
-        : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+        : mFd(-1), mFileName(NULL), mFileLength(-1),
+          mDirectoryMap(NULL),
+          mNumEntries(-1), mDirectoryOffset(-1),
+          mHashTableSize(-1), mHashTable(NULL)
         {}
     ~ZipFileRO() {
         free(mHashTable);
-        if (mFileMap)
-            mFileMap->release();
+        if (mDirectoryMap)
+            mDirectoryMap->release();
         if (mFd >= 0)
             close(mFd);
+        if (mFileName)
+            free(mFileName);
     }
 
     /*
@@ -118,8 +123,8 @@
      * Returns "false" if "entry" is bogus or if the data in the Zip file
      * appears to be bad.
      */
-    bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
-        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+    bool getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
 
     /*
      * Create a new FileMap object that maps a subset of the archive.  For
@@ -155,13 +160,13 @@
      * Utility function: uncompress deflated data, buffer to buffer.
      */
     static bool inflateBuffer(void* outBuf, const void* inBuf,
-        long uncompLen, long compLen);
+        size_t uncompLen, size_t compLen);
 
     /*
      * Utility function: uncompress deflated data, buffer to fd.
      */
     static bool inflateBuffer(int fd, const void* inBuf,
-        long uncompLen, long compLen);
+        size_t uncompLen, size_t compLen);
 
     /*
      * Some basic functions for raw data manipulation.  "LE" means
@@ -179,6 +184,9 @@
     ZipFileRO(const ZipFileRO& src);
     ZipFileRO& operator=(const ZipFileRO& src);
 
+    /* locate and parse the central directory */
+    bool mapCentralDirectory(void);
+
     /* parse the archive, prepping internal structures */
     bool parseZipArchive(void);
 
@@ -203,12 +211,21 @@
     /* open Zip archive */
     int         mFd;
 
+    /* zip file name */
+    char*       mFileName;
+
+    /* length of file */
+    size_t      mFileLength;
+
     /* mapped file */
-    FileMap*    mFileMap;
+    FileMap*    mDirectoryMap;
 
     /* number of entries in the Zip archive */
     int         mNumEntries;
 
+    /* CD directory offset in the Zip archive */
+    off_t       mDirectoryOffset;
+
     /*
      * We know how many entries are in the Zip archive, so we have a
      * fixed-size hash table.  We probe for an empty slot.
diff --git a/include/utils/threads.h b/include/utils/threads.h
index 5ac0c5e..1bcfaed 100644
--- a/include/utils/threads.h
+++ b/include/utils/threads.h
@@ -295,6 +295,96 @@
 
 /*****************************************************************************/
 
+#if defined(HAVE_PTHREADS)
+
+/*
+ * Simple mutex class.  The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it.  They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class RWLock {
+public:
+    enum {
+        PRIVATE = 0,
+        SHARED = 1
+    };
+
+                RWLock();
+                RWLock(const char* name);
+                RWLock(int type, const char* name = NULL);
+                ~RWLock();
+
+    status_t    readLock();
+    status_t    tryReadLock();
+    status_t    writeLock();
+    status_t    tryWriteLock();
+    void        unlock();
+
+    class AutoRLock {
+    public:
+        inline AutoRLock(RWLock& rwlock) : mLock(rwlock)  { mLock.readLock(); }
+        inline ~AutoRLock() { mLock.unlock(); }
+    private:
+        RWLock& mLock;
+    };
+
+    class AutoWLock {
+    public:
+        inline AutoWLock(RWLock& rwlock) : mLock(rwlock)  { mLock.writeLock(); }
+        inline ~AutoWLock() { mLock.unlock(); }
+    private:
+        RWLock& mLock;
+    };
+
+private:
+    // A RWLock cannot be copied
+                RWLock(const RWLock&);
+   RWLock&      operator = (const RWLock&);
+
+   pthread_rwlock_t mRWLock;
+};
+
+inline RWLock::RWLock() {
+    pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(const char* name) {
+    pthread_rwlock_init(&mRWLock, NULL);
+}
+inline RWLock::RWLock(int type, const char* name) {
+    if (type == SHARED) {
+        pthread_rwlockattr_t attr;
+        pthread_rwlockattr_init(&attr);
+        pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+        pthread_rwlock_init(&mRWLock, &attr);
+        pthread_rwlockattr_destroy(&attr);
+    } else {
+        pthread_rwlock_init(&mRWLock, NULL);
+    }
+}
+inline RWLock::~RWLock() {
+    pthread_rwlock_destroy(&mRWLock);
+}
+inline status_t RWLock::readLock() {
+    return -pthread_rwlock_rdlock(&mRWLock);
+}
+inline status_t RWLock::tryReadLock() {
+    return -pthread_rwlock_tryrdlock(&mRWLock);
+}
+inline status_t RWLock::writeLock() {
+    return -pthread_rwlock_wrlock(&mRWLock);
+}
+inline status_t RWLock::tryWriteLock() {
+    return -pthread_rwlock_trywrlock(&mRWLock);
+}
+inline void RWLock::unlock() {
+    pthread_rwlock_unlock(&mRWLock);
+}
+
+#endif // HAVE_PTHREADS
+
+/*****************************************************************************/
+
 /*
  * Condition variable class.  The implementation is system-dependent.
  *
diff --git a/libs/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..a3e117f 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -367,6 +367,26 @@
     return token;
 }
 
+void IPCThreadState::setStrictModePolicy(int32_t policy)
+{
+    mStrictModePolicy = policy;
+}
+
+int32_t IPCThreadState::getStrictModePolicy() const
+{
+    return mStrictModePolicy;
+}
+
+void IPCThreadState::setLastTransactionBinderFlags(int32_t flags)
+{
+    mLastTransactionBinderFlags = flags;
+}
+
+int32_t IPCThreadState::getLastTransactionBinderFlags() const
+{
+    return mLastTransactionBinderFlags;
+}
+
 void IPCThreadState::restoreCallingIdentity(int64_t token)
 {
     mCallingUid = (int)(token>>32);
@@ -588,7 +608,10 @@
 }
 
 IPCThreadState::IPCThreadState()
-    : mProcess(ProcessState::self()), mMyThreadId(androidGetTid())
+    : mProcess(ProcessState::self()),
+      mMyThreadId(androidGetTid()),
+      mStrictModePolicy(0),
+      mLastTransactionBinderFlags(0)
 {
     pthread_setspecific(gTLS, this);
     clearCaller();
@@ -972,11 +995,11 @@
             }
             if (tr.target.ptr) {
                 sp<BBinder> b((BBinder*)tr.cookie);
-                const status_t error = b->transact(tr.code, buffer, &reply, 0);
+                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
                 if (error < NO_ERROR) reply.setError(error);
-                
+
             } else {
-                const status_t error = the_context_object->transact(tr.code, buffer, &reply, 0);
+                const status_t error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
                 if (error < NO_ERROR) reply.setError(error);
             }
             
diff --git a/libs/binder/IPermissionController.cpp b/libs/binder/IPermissionController.cpp
index bff4c9b..e13036f 100644
--- a/libs/binder/IPermissionController.cpp
+++ b/libs/binder/IPermissionController.cpp
@@ -36,7 +36,7 @@
         : BpInterface<IPermissionController>(impl)
     {
     }
-        
+
     virtual bool checkPermission(const String16& permission, int32_t pid, int32_t uid)
     {
         Parcel data, reply;
@@ -46,7 +46,7 @@
         data.writeInt32(uid);
         remote()->transact(CHECK_PERMISSION_TRANSACTION, data, &reply);
         // fail on exception
-        if (reply.readInt32() != 0) return 0;
+        if (reply.readExceptionCode() != 0) return 0;
         return reply.readInt32() != 0;
     }
 };
@@ -66,8 +66,7 @@
             int32_t pid = data.readInt32();
             int32_t uid = data.readInt32();
             bool res = checkPermission(permission, pid, uid);
-            // write exception
-            reply->writeInt32(0);
+            reply->writeNoException();
             reply->writeInt32(res ? 1 : 0);
             return NO_ERROR;
         } break;
@@ -77,4 +76,3 @@
 }
 
 }; // namespace android
-
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 0cf4158..1fa4c35 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -129,19 +129,19 @@
         : BpInterface<IServiceManager>(impl)
     {
     }
-        
+
     virtual sp<IBinder> getService(const String16& name) const
     {
         unsigned n;
         for (n = 0; n < 5; n++){
             sp<IBinder> svc = checkService(name);
             if (svc != NULL) return svc;
-            LOGI("Waiting for sevice %s...\n", String8(name).string());
+            LOGI("Waiting for service %s...\n", String8(name).string());
             sleep(1);
         }
         return NULL;
     }
-    
+
     virtual sp<IBinder> checkService( const String16& name) const
     {
         Parcel data, reply;
@@ -158,7 +158,7 @@
         data.writeString16(name);
         data.writeStrongBinder(service);
         status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
-        return err == NO_ERROR ? reply.readInt32() : err;
+        return err == NO_ERROR ? reply.readExceptionCode() : err;
     }
 
     virtual Vector<String16> listServices()
@@ -226,4 +226,3 @@
 }
 
 }; // namespace android
-
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 00d2210..f329ac4 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -19,6 +19,7 @@
 
 #include <binder/Parcel.h>
 
+#include <binder/IPCThreadState.h>
 #include <binder/Binder.h>
 #include <binder/BpBinder.h>
 #include <utils/Debug.h>
@@ -47,6 +48,12 @@
 
 #define PAD_SIZE(s) (((s)+3)&~3)
 
+// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
+#define STRICT_MODE_PENALTY_GATHER 0x100
+
+// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
+#define EX_HAS_REPLY_HEADER -128
+
 // XXX This can be made public if we want to provide
 // support for typed data.
 struct small_flat_data
@@ -436,19 +443,37 @@
     return mHasFds;
 }
 
+// Write RPC headers.  (previously just the interface token)
 status_t Parcel::writeInterfaceToken(const String16& interface)
 {
+    writeInt32(IPCThreadState::self()->getStrictModePolicy() |
+               STRICT_MODE_PENALTY_GATHER);
     // currently the interface identification token is just its name as a string
     return writeString16(interface);
 }
 
 bool Parcel::checkInterface(IBinder* binder) const
 {
-    return enforceInterface(binder->getInterfaceDescriptor()); 
+    return enforceInterface(binder->getInterfaceDescriptor());
 }
 
-bool Parcel::enforceInterface(const String16& interface) const
+bool Parcel::enforceInterface(const String16& interface,
+                              IPCThreadState* threadState) const
 {
+    int32_t strictPolicy = readInt32();
+    if (threadState == NULL) {
+        threadState = IPCThreadState::self();
+    }
+    if ((threadState->getLastTransactionBinderFlags() &
+         IBinder::FLAG_ONEWAY) != 0) {
+      // For one-way calls, the callee is running entirely
+      // disconnected from the caller, so disable StrictMode entirely.
+      // Not only does disk/network usage not impact the caller, but
+      // there's no way to commuicate back any violations anyway.
+      threadState->setStrictModePolicy(0);
+    } else {
+      threadState->setStrictModePolicy(strictPolicy);
+    }
     const String16 str(readString16());
     if (str == interface) {
         return true;
@@ -457,7 +482,7 @@
                 String8(interface).string(), String8(str).string());
         return false;
     }
-} 
+}
 
 const size_t* Parcel::objects() const
 {
@@ -750,6 +775,11 @@
     goto restart_write;
 }
 
+status_t Parcel::writeNoException()
+{
+    return writeInt32(0);
+}
+
 void Parcel::remove(size_t start, size_t amt)
 {
     LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
@@ -938,6 +968,20 @@
     return val;
 }
 
+int32_t Parcel::readExceptionCode() const
+{
+  int32_t exception_code = readAligned<int32_t>();
+  if (exception_code == EX_HAS_REPLY_HEADER) {
+    int32_t header_size = readAligned<int32_t>();
+    // Skip over fat responses headers.  Not used (or propagated) in
+    // native code
+    setDataPosition(dataPosition() + header_size);
+    // And fat response headers are currently only used when there are no
+    // exceptions, so return no error:
+    return 0;
+  }
+  return exception_code;
+}
 
 native_handle* Parcel::readNativeHandle() const
 {
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
new file mode 100644
index 0000000..249558a
--- /dev/null
+++ b/libs/gui/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	ISensorEventConnection.cpp \
+	ISensorServer.cpp \
+	Sensor.cpp \
+	SensorChannel.cpp \
+	SensorEventQueue.cpp \
+	SensorManager.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libhardware \
+	libhardware_legacy
+
+LOCAL_MODULE:= libgui
+
+ifeq ($(TARGET_SIMULATOR),true)
+    LOCAL_LDLIBS += -lpthread
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
new file mode 100644
index 0000000..a5083fe
--- /dev/null
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/ISensorEventConnection.h>
+#include <gui/SensorChannel.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_SENSOR_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
+    ENABLE_DISABLE,
+    SET_EVENT_RATE
+};
+
+class BpSensorEventConnection : public BpInterface<ISensorEventConnection>
+{
+public:
+    BpSensorEventConnection(const sp<IBinder>& impl)
+        : BpInterface<ISensorEventConnection>(impl)
+    {
+    }
+
+    virtual sp<SensorChannel> getSensorChannel() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        remote()->transact(GET_SENSOR_CHANNEL, data, &reply);
+        return new SensorChannel(reply);
+    }
+
+    virtual status_t enableDisable(int handle, bool enabled)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt32(enabled);
+        remote()->transact(ENABLE_DISABLE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setEventRate(int handle, nsecs_t ns)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
+        data.writeInt32(handle);
+        data.writeInt64(ns);
+        remote()->transact(SET_EVENT_RATE, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
+
+// ----------------------------------------------------------------------------
+
+status_t BnSensorEventConnection::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_SENSOR_CHANNEL: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            sp<SensorChannel> channel(getSensorChannel());
+            channel->writeToParcel(reply);
+            return NO_ERROR;
+        } break;
+        case ENABLE_DISABLE: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            int enabled = data.readInt32();
+            status_t result = enableDisable(handle, enabled);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+        case SET_EVENT_RATE: {
+            CHECK_INTERFACE(ISensorEventConnection, data, reply);
+            int handle = data.readInt32();
+            int ns = data.readInt64();
+            status_t result = setEventRate(handle, ns);
+            reply->writeInt32(result);
+            return NO_ERROR;
+        } break;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
new file mode 100644
index 0000000..7111092
--- /dev/null
+++ b/libs/gui/ISensorServer.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/Sensor.h>
+#include <gui/ISensorServer.h>
+#include <gui/ISensorEventConnection.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+    GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
+    CREATE_SENSOR_EVENT_CONNECTION,
+};
+
+class BpSensorServer : public BpInterface<ISensorServer>
+{
+public:
+    BpSensorServer(const sp<IBinder>& impl)
+        : BpInterface<ISensorServer>(impl)
+    {
+    }
+
+    virtual Vector<Sensor> getSensorList()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        remote()->transact(GET_SENSOR_LIST, data, &reply);
+        Sensor s;
+        Vector<Sensor> v;
+        int32_t n = reply.readInt32();
+        v.setCapacity(n);
+        while (n--) {
+            reply.read(static_cast<Flattenable&>(s));
+            v.add(s);
+        }
+        return v;
+    }
+
+    virtual sp<ISensorEventConnection> createSensorEventConnection()
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply);
+        return interface_cast<ISensorEventConnection>(reply.readStrongBinder());
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
+
+// ----------------------------------------------------------------------
+
+status_t BnSensorServer::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    switch(code) {
+        case GET_SENSOR_LIST: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            Vector<Sensor> v(getSensorList());
+            size_t n = v.size();
+            reply->writeInt32(n);
+            for (size_t i=0 ; i<n ; i++) {
+                reply->write(static_cast<const Flattenable&>(v[i]));
+            }
+            return NO_ERROR;
+        } break;
+        case CREATE_SENSOR_EVENT_CONNECTION: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            sp<ISensorEventConnection> connection(createSensorEventConnection());
+            reply->writeStrongBinder(connection->asBinder());
+            return NO_ERROR;
+        } break;
+    }
+    return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
new file mode 100644
index 0000000..b1f37ff
--- /dev/null
+++ b/libs/gui/Sensor.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/String8.h>
+#include <utils/Flattenable.h>
+
+#include <hardware/sensors.h>
+
+#include <gui/Sensor.h>
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+Sensor::Sensor()
+    : mHandle(0), mType(0),
+      mMinValue(0), mMaxValue(0), mResolution(0),
+      mPower(0), mMinDelay(0)
+{
+}
+
+Sensor::Sensor(struct sensor_t const* hwSensor)
+{
+    mName = hwSensor->name;
+    mVendor = hwSensor->vendor;
+    mHandle = hwSensor->handle;
+    mType = hwSensor->type;
+    mMinValue = 0;                      // FIXME: minValue
+    mMaxValue = hwSensor->maxRange;     // FIXME: maxValue
+    mResolution = hwSensor->resolution;
+    mPower = hwSensor->power;
+    mMinDelay = hwSensor->minDelay;
+}
+
+Sensor::~Sensor()
+{
+}
+
+const String8& Sensor::getName() const {
+    return mName;
+}
+
+const String8& Sensor::getVendor() const {
+    return mVendor;
+}
+
+int32_t Sensor::getHandle() const {
+    return mHandle;
+}
+
+int32_t Sensor::getType() const {
+    return mType;
+}
+
+float Sensor::getMinValue() const {
+    return mMinValue;
+}
+
+float Sensor::getMaxValue() const {
+    return mMaxValue;
+}
+
+float Sensor::getResolution() const {
+    return mResolution;
+}
+
+float Sensor::getPowerUsage() const {
+    return mPower;
+}
+
+int32_t Sensor::getMinDelay() const {
+    return mMinDelay;
+}
+
+size_t Sensor::getFlattenedSize() const
+{
+    return  sizeof(int32_t) + ((mName.length() + 3) & ~3) +
+            sizeof(int32_t) + ((mVendor.length() + 3) & ~3) +
+            sizeof(int32_t) * 2 +
+            sizeof(float) * 4 +
+            sizeof(int32_t);
+}
+
+size_t Sensor::getFdCount() const
+{
+    return 0;
+}
+
+static inline
+size_t write(void* buffer, size_t offset, const String8& value) {
+    memcpy(static_cast<char*>(buffer) + offset, value.string(), value.length());
+    return (value.length() + 3) & ~3;
+}
+
+static inline
+size_t write(void* buffer, size_t offset, float value) {
+    *reinterpret_cast<float*>(static_cast<char*>(buffer) + offset) = value;
+    return sizeof(float);
+}
+
+static inline
+size_t write(void* buffer, size_t offset, int32_t value) {
+    *reinterpret_cast<int32_t*>(static_cast<char*>(buffer) + offset) = value;
+    return sizeof(int32_t);
+}
+
+status_t Sensor::flatten(void* buffer, size_t size,
+        int fds[], size_t count) const
+{
+    if (size < Sensor::getFlattenedSize())
+        return -ENOMEM;
+
+    size_t offset = 0;
+    offset += write(buffer, offset, int32_t(mName.length()));
+    offset += write(buffer, offset, mName);
+    offset += write(buffer, offset, int32_t(mVendor.length()));
+    offset += write(buffer, offset, mVendor);
+    offset += write(buffer, offset, mHandle);
+    offset += write(buffer, offset, mType);
+    offset += write(buffer, offset, mMinValue);
+    offset += write(buffer, offset, mMaxValue);
+    offset += write(buffer, offset, mResolution);
+    offset += write(buffer, offset, mPower);
+    offset += write(buffer, offset, mMinDelay);
+
+    return NO_ERROR;
+}
+
+static inline
+size_t read(void const* buffer, size_t offset, String8* value, int32_t len) {
+    value->setTo(static_cast<char const*>(buffer) + offset, len);
+    return (len + 3) & ~3;
+}
+
+static inline
+size_t read(void const* buffer, size_t offset, float* value) {
+    *value = *reinterpret_cast<float const*>(static_cast<char const*>(buffer) + offset);
+    return sizeof(float);
+}
+
+static inline
+size_t read(void const* buffer, size_t offset, int32_t* value) {
+    *value = *reinterpret_cast<int32_t const*>(static_cast<char const*>(buffer) + offset);
+    return sizeof(int32_t);
+}
+
+status_t Sensor::unflatten(void const* buffer, size_t size,
+        int fds[], size_t count)
+{
+    int32_t len;
+    size_t offset = 0;
+    offset += read(buffer, offset, &len);
+    offset += read(buffer, offset, &mName, len);
+    offset += read(buffer, offset, &len);
+    offset += read(buffer, offset, &mVendor, len);
+    offset += read(buffer, offset, &mHandle);
+    offset += read(buffer, offset, &mType);
+    offset += read(buffer, offset, &mMinValue);
+    offset += read(buffer, offset, &mMaxValue);
+    offset += read(buffer, offset, &mResolution);
+    offset += read(buffer, offset, &mPower);
+    offset += read(buffer, offset, &mMinDelay);
+
+    return NO_ERROR;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/SensorChannel.cpp b/libs/gui/SensorChannel.cpp
new file mode 100644
index 0000000..147e1c2
--- /dev/null
+++ b/libs/gui/SensorChannel.cpp
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <unistd.h>
+#include <fcntl.h>
+
+#include <utils/Errors.h>
+
+#include <binder/Parcel.h>
+
+#include <gui/SensorChannel.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+SensorChannel::SensorChannel()
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    int fds[2];
+    if (pipe(fds) == 0) {
+        mReceiveFd = fds[0];
+        mSendFd = fds[1];
+        fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
+        fcntl(mSendFd, F_SETFL, O_NONBLOCK);
+    }
+}
+
+SensorChannel::SensorChannel(const Parcel& data)
+    : mSendFd(-1), mReceiveFd(-1)
+{
+    mReceiveFd = dup(data.readFileDescriptor());
+    fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
+}
+
+SensorChannel::~SensorChannel()
+{
+    if (mSendFd >= 0)
+        close(mSendFd);
+
+    if (mReceiveFd >= 0)
+        close(mReceiveFd);
+}
+
+int SensorChannel::getFd() const
+{
+    return mReceiveFd;
+}
+
+ssize_t SensorChannel::write(void const* vaddr, size_t size)
+{
+    ssize_t len = ::write(mSendFd, vaddr, size);
+    if (len < 0)
+        return -errno;
+    return len;
+}
+
+ssize_t SensorChannel::read(void* vaddr, size_t size)
+{
+    ssize_t len = ::read(mReceiveFd, vaddr, size);
+    if (len < 0)
+        return -errno;
+    return len;
+}
+
+status_t SensorChannel::writeToParcel(Parcel* reply) const
+{
+    if (mReceiveFd < 0)
+        return -EINVAL;
+
+    status_t result = reply->writeDupFileDescriptor(mReceiveFd);
+    close(mReceiveFd);
+    mReceiveFd = -1;
+    return result;
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
new file mode 100644
index 0000000..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/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..5c111f6 100644
--- a/libs/surfaceflinger_client/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -46,13 +46,22 @@
     {
     }
 
-    virtual sp<ISurfaceFlingerClient> createConnection()
+    virtual sp<ISurfaceComposerClient> createConnection()
     {
         uint32_t n;
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
-        return interface_cast<ISurfaceFlingerClient>(reply.readStrongBinder());
+        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
+    }
+
+    virtual sp<ISurfaceComposerClient> createClientConnection()
+    {
+        uint32_t n;
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
+        remote()->transact(BnSurfaceComposer::CREATE_CLIENT_CONNECTION, data, &reply);
+        return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
     virtual sp<IMemoryHeap> getCblk() const
@@ -136,6 +145,11 @@
             sp<IBinder> b = createConnection()->asBinder();
             reply->writeStrongBinder(b);
         } break;
+        case CREATE_CLIENT_CONNECTION: {
+            CHECK_INTERFACE(ISurfaceComposer, data, reply);
+            sp<IBinder> b = createClientConnection()->asBinder();
+            reply->writeStrongBinder(b);
+        } break;
         case OPEN_GLOBAL_TRANSACTION: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             openGlobalTransaction();
diff --git a/libs/surfaceflinger_client/ISurfaceComposerClient.cpp b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
new file mode 100644
index 0000000..2cc1f8e
--- /dev/null
+++ b/libs/surfaceflinger_client/ISurfaceComposerClient.cpp
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// tag as surfaceflinger
+#define LOG_TAG "SurfaceFlinger"
+
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <binder/Parcel.h>
+#include <binder/IMemory.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#include <ui/Point.h>
+#include <ui/Rect.h>
+
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
+#include <private/surfaceflinger/LayerState.h>
+
+// ---------------------------------------------------------------------------
+
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
+#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
+#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+enum {
+    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
+    GET_TOKEN,
+    CREATE_SURFACE,
+    DESTROY_SURFACE,
+    SET_STATE
+};
+
+class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient>
+{
+public:
+    BpSurfaceComposerClient(const sp<IBinder>& impl)
+        : BpInterface<ISurfaceComposerClient>(impl)
+    {
+    }
+
+    virtual sp<IMemoryHeap> getControlBlock() const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        remote()->transact(GET_CBLK, data, &reply);
+        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
+    }
+
+    virtual ssize_t getTokenForSurface(const sp<ISurface>& sur) const
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeStrongBinder(sur->asBinder());
+        remote()->transact(GET_TOKEN, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual sp<ISurface> createSurface( surface_data_t* params,
+                                        int pid,
+                                        const String8& name,
+                                        DisplayID display,
+                                        uint32_t w,
+                                        uint32_t h,
+                                        PixelFormat format,
+                                        uint32_t flags)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeInt32(pid);
+        data.writeString8(name);
+        data.writeInt32(display);
+        data.writeInt32(w);
+        data.writeInt32(h);
+        data.writeInt32(format);
+        data.writeInt32(flags);
+        remote()->transact(CREATE_SURFACE, data, &reply);
+        params->readFromParcel(reply);
+        return interface_cast<ISurface>(reply.readStrongBinder());
+    }
+
+    virtual status_t destroySurface(SurfaceID sid)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeInt32(sid);
+        remote()->transact(DESTROY_SURFACE, data, &reply);
+        return reply.readInt32();
+    }
+
+    virtual status_t setState(int32_t count, const layer_state_t* states)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
+        data.writeInt32(count);
+        for (int i=0 ; i<count ; i++)
+            states[i].write(data);
+        remote()->transact(SET_STATE, data, &reply);
+        return reply.readInt32();
+    }
+};
+
+IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
+
+// ----------------------------------------------------------------------
+
+status_t BnSurfaceComposerClient::onTransact(
+    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+    // codes that don't require permission check
+
+    switch(code) {
+        case GET_CBLK: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            sp<IMemoryHeap> ctl(getControlBlock());
+            reply->writeStrongBinder(ctl->asBinder());
+            return NO_ERROR;
+        } break;
+        case GET_TOKEN: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            sp<ISurface> sur = interface_cast<ISurface>(data.readStrongBinder());
+            ssize_t token = getTokenForSurface(sur);
+            reply->writeInt32(token);
+            return NO_ERROR;
+        } break;
+    }
+
+    // these must be checked
+
+     IPCThreadState* ipc = IPCThreadState::self();
+     const int pid = ipc->getCallingPid();
+     const int uid = ipc->getCallingUid();
+     const int self_pid = getpid();
+     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
+         // we're called from a different process, do the real check
+         if (!checkCallingPermission(
+                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
+         {
+             LOGE("Permission Denial: "
+                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
+             return PERMISSION_DENIED;
+         }
+     }
+
+     switch(code) {
+        case CREATE_SURFACE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            surface_data_t params;
+            int32_t pid = data.readInt32();
+            String8 name = data.readString8();
+            DisplayID display = data.readInt32();
+            uint32_t w = data.readInt32();
+            uint32_t h = data.readInt32();
+            PixelFormat format = data.readInt32();
+            uint32_t flags = data.readInt32();
+            sp<ISurface> s = createSurface(&params, pid, name, display, w, h,
+                    format, flags);
+            params.writeToParcel(reply);
+            reply->writeStrongBinder(s->asBinder());
+            return NO_ERROR;
+        } break;
+        case DESTROY_SURFACE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            reply->writeInt32( destroySurface( data.readInt32() ) );
+            return NO_ERROR;
+        } break;
+        case SET_STATE: {
+            CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
+            int32_t count = data.readInt32();
+            layer_state_t* states = new layer_state_t[count];
+            for (int i=0 ; i<count ; i++)
+                states[i].read(data);
+            status_t err = setState(count, states);
+            delete [] states;
+            reply->writeInt32(err);
+            return NO_ERROR;
+        } break;
+        default:
+            return BBinder::onTransact(code, data, reply, flags);
+    }
+}
+
+// ----------------------------------------------------------------------
+
+status_t ISurfaceComposerClient::surface_data_t::readFromParcel(const Parcel& parcel)
+{
+    token    = parcel.readInt32();
+    identity = parcel.readInt32();
+    width    = parcel.readInt32();
+    height   = parcel.readInt32();
+    format   = parcel.readInt32();
+    return NO_ERROR;
+}
+
+status_t ISurfaceComposerClient::surface_data_t::writeToParcel(Parcel* parcel) const
+{
+    parcel->writeInt32(token);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(width);
+    parcel->writeInt32(height);
+    parcel->writeInt32(format);
+    return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp b/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
deleted file mode 100644
index def96d7..0000000
--- a/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <binder/Parcel.h>
-#include <binder/IMemory.h>
-#include <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-
-#include <ui/Point.h>
-#include <ui/Rect.h>
-
-#include <surfaceflinger/ISurface.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
-#include <private/surfaceflinger/LayerState.h>
-
-// ---------------------------------------------------------------------------
-
-/* ideally AID_GRAPHICS would be in a semi-public header
- * or there would be a way to map a user/group name to its id
- */
-#ifndef AID_GRAPHICS
-#define AID_GRAPHICS 1003
-#endif
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-// ---------------------------------------------------------------------------
-
-namespace android {
-
-enum {
-    GET_CBLK = IBinder::FIRST_CALL_TRANSACTION,
-    CREATE_SURFACE,
-    DESTROY_SURFACE,
-    SET_STATE
-};
-
-class BpSurfaceFlingerClient : public BpInterface<ISurfaceFlingerClient>
-{
-public:
-    BpSurfaceFlingerClient(const sp<IBinder>& impl)
-        : BpInterface<ISurfaceFlingerClient>(impl)
-    {
-    }
-
-    virtual sp<IMemoryHeap> getControlBlock() const
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        remote()->transact(GET_CBLK, data, &reply);
-        return interface_cast<IMemoryHeap>(reply.readStrongBinder());
-    }
-
-    virtual sp<ISurface> createSurface( surface_data_t* params,
-                                        int pid,
-                                        const String8& name,
-                                        DisplayID display,
-                                        uint32_t w,
-                                        uint32_t h,
-                                        PixelFormat format,
-                                        uint32_t flags)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(pid);
-        data.writeString8(name);
-        data.writeInt32(display);
-        data.writeInt32(w);
-        data.writeInt32(h);
-        data.writeInt32(format);
-        data.writeInt32(flags);
-        remote()->transact(CREATE_SURFACE, data, &reply);
-        params->readFromParcel(reply);
-        return interface_cast<ISurface>(reply.readStrongBinder());
-    }
-                                    
-    virtual status_t destroySurface(SurfaceID sid)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(sid);
-        remote()->transact(DESTROY_SURFACE, data, &reply);
-        return reply.readInt32();
-    }
-
-    virtual status_t setState(int32_t count, const layer_state_t* states)
-    {
-        Parcel data, reply;
-        data.writeInterfaceToken(ISurfaceFlingerClient::getInterfaceDescriptor());
-        data.writeInt32(count);
-        for (int i=0 ; i<count ; i++)
-            states[i].write(data);
-        remote()->transact(SET_STATE, data, &reply);
-        return reply.readInt32();
-    }
-};
-
-IMPLEMENT_META_INTERFACE(SurfaceFlingerClient, "android.ui.ISurfaceFlingerClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceFlingerClient::onTransact(
-    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
-    // codes that don't require permission check
-
-    switch(code) {
-        case GET_CBLK: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            sp<IMemoryHeap> ctl(getControlBlock());
-            reply->writeStrongBinder(ctl->asBinder());
-            return NO_ERROR;
-        } break;
-    }
-
-    // these must be checked
-     
-     IPCThreadState* ipc = IPCThreadState::self();
-     const int pid = ipc->getCallingPid();
-     const int uid = ipc->getCallingUid();
-     const int self_pid = getpid();
-     if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
-         // we're called from a different process, do the real check
-         if (!checkCallingPermission(
-                 String16("android.permission.ACCESS_SURFACE_FLINGER")))
-         {
-             LOGE("Permission Denial: "
-                     "can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
-             return PERMISSION_DENIED;
-         }
-     }
-   
-     switch(code) {
-        case CREATE_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            surface_data_t params;
-            int32_t pid = data.readInt32();
-            String8 name = data.readString8();
-            DisplayID display = data.readInt32();
-            uint32_t w = data.readInt32();
-            uint32_t h = data.readInt32();
-            PixelFormat format = data.readInt32();
-            uint32_t flags = data.readInt32();
-            sp<ISurface> s = createSurface(&params, pid, name, display, w, h,
-                    format, flags);
-            params.writeToParcel(reply);
-            reply->writeStrongBinder(s->asBinder());
-            return NO_ERROR;
-        } break;
-        case DESTROY_SURFACE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            reply->writeInt32( destroySurface( data.readInt32() ) );
-            return NO_ERROR;
-        } break;
-        case SET_STATE: {
-            CHECK_INTERFACE(ISurfaceFlingerClient, data, reply);
-            int32_t count = data.readInt32();
-            layer_state_t* states = new layer_state_t[count];
-            for (int i=0 ; i<count ; i++)
-                states[i].read(data);
-            status_t err = setState(count, states);
-            delete [] states;
-            reply->writeInt32(err);
-            return NO_ERROR;
-        } break;
-        default:
-            return BBinder::onTransact(code, data, reply, flags);
-    }
-}
-
-// ----------------------------------------------------------------------
-
-status_t ISurfaceFlingerClient::surface_data_t::readFromParcel(const Parcel& parcel)
-{
-    token    = parcel.readInt32();
-    identity = parcel.readInt32();
-    width    = parcel.readInt32();
-    height   = parcel.readInt32();
-    format   = parcel.readInt32();
-    return NO_ERROR;
-}
-
-status_t ISurfaceFlingerClient::surface_data_t::writeToParcel(Parcel* parcel) const
-{
-    parcel->writeInt32(token);
-    parcel->writeInt32(identity);
-    parcel->writeInt32(width);
-    parcel->writeInt32(height);
-    parcel->writeInt32(format);
-    return NO_ERROR;
-}
-
-}; // namespace android
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index a17e8ac..38b2fae 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -44,15 +44,11 @@
 
 // these functions are used by the clients
 status_t SharedClient::validate(size_t i) const {
-    if (uint32_t(i) >= uint32_t(NUM_LAYERS_MAX))
+    if (uint32_t(i) >= uint32_t(SharedBufferStack::NUM_LAYERS_MAX))
         return BAD_INDEX;
     return surfaces[i].status;
 }
 
-uint32_t SharedClient::getIdentity(size_t token) const {
-    return uint32_t(surfaces[token].identity);
-}
-
 // ----------------------------------------------------------------------------
 
 
@@ -62,24 +58,60 @@
 
 void SharedBufferStack::init(int32_t i)
 {
-    inUse = -1;
+    inUse = -2;
     status = NO_ERROR;
     identity = i;
 }
 
+status_t SharedBufferStack::setCrop(int buffer, const Rect& crop)
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return BAD_INDEX;
+
+    buffers[buffer].crop.l = uint16_t(crop.left);
+    buffers[buffer].crop.t = uint16_t(crop.top);
+    buffers[buffer].crop.r = uint16_t(crop.right);
+    buffers[buffer].crop.b = uint16_t(crop.bottom);
+    return NO_ERROR;
+}
+
+status_t SharedBufferStack::setTransform(int buffer, uint8_t transform)
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return BAD_INDEX;
+    buffers[buffer].transform = transform;
+    return NO_ERROR;
+}
+
 status_t SharedBufferStack::setDirtyRegion(int buffer, const Region& dirty)
 {
     if (uint32_t(buffer) >= NUM_BUFFER_MAX)
         return BAD_INDEX;
 
-    // in the current implementation we only send a single rectangle
-    const Rect bounds(dirty.getBounds());
-    FlatRegion& reg(dirtyRegion[buffer]);
-    reg.count = 1;
-    reg.rects[0] = uint16_t(bounds.left);
-    reg.rects[1] = uint16_t(bounds.top);
-    reg.rects[2] = uint16_t(bounds.right);
-    reg.rects[3] = uint16_t(bounds.bottom);
+    FlatRegion& reg(buffers[buffer].dirtyRegion);
+    if (dirty.isEmpty()) {
+        reg.count = 0;
+        return NO_ERROR;
+    }
+
+    size_t count;
+    Rect const* r = dirty.getArray(&count);
+    if (count > FlatRegion::NUM_RECT_MAX) {
+        const Rect bounds(dirty.getBounds());
+        reg.count = 1;
+        reg.rects[0].l = uint16_t(bounds.left);
+        reg.rects[0].t = uint16_t(bounds.top);
+        reg.rects[0].r = uint16_t(bounds.right);
+        reg.rects[0].b = uint16_t(bounds.bottom);
+    } else {
+        reg.count = count;
+        for (size_t i=0 ; i<count ; i++) {
+            reg.rects[i].l = uint16_t(r[i].left);
+            reg.rects[i].t = uint16_t(r[i].top);
+            reg.rects[i].r = uint16_t(r[i].right);
+            reg.rects[i].b = uint16_t(r[i].bottom);
+        }
+    }
     return NO_ERROR;
 }
 
@@ -89,18 +121,57 @@
     if (uint32_t(buffer) >= NUM_BUFFER_MAX)
         return res;
 
-    const FlatRegion& reg(dirtyRegion[buffer]);
-    res.set(Rect(reg.rects[0], reg.rects[1], reg.rects[2], reg.rects[3]));
+    const FlatRegion& reg(buffers[buffer].dirtyRegion);
+    if (reg.count > FlatRegion::NUM_RECT_MAX)
+        return res;
+
+    if (reg.count == 1) {
+        const Rect r(
+                reg.rects[0].l,
+                reg.rects[0].t,
+                reg.rects[0].r,
+                reg.rects[0].b);
+        res.set(r);
+    } else {
+        for (size_t i=0 ; i<reg.count ; i++) {
+            const Rect r(
+                    reg.rects[i].l,
+                    reg.rects[i].t,
+                    reg.rects[i].r,
+                    reg.rects[i].b);
+            res.orSelf(r);
+        }
+    }
     return res;
 }
 
+Rect SharedBufferStack::getCrop(int buffer) const
+{
+    Rect res(-1, -1);
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return res;
+    res.left = buffers[buffer].crop.l;
+    res.top = buffers[buffer].crop.t;
+    res.right = buffers[buffer].crop.r;
+    res.bottom = buffers[buffer].crop.b;
+    return res;
+}
+
+uint32_t SharedBufferStack::getTransform(int buffer) const
+{
+    if (uint32_t(buffer) >= NUM_BUFFER_MAX)
+        return 0;
+    return buffers[buffer].transform;
+}
+
+
 // ----------------------------------------------------------------------------
 
 SharedBufferBase::SharedBufferBase(SharedClient* sharedClient,
-        int surface, int num, int32_t identity)
+        int surface, int32_t identity)
     : mSharedClient(sharedClient), 
       mSharedStack(sharedClient->surfaces + surface),
-      mNumBuffers(num), mIdentity(identity)
+      mIdentity(identity)
 {
 }
 
@@ -108,22 +179,16 @@
 {
 }
 
-uint32_t SharedBufferBase::getIdentity()
-{
-    SharedBufferStack& stack( *mSharedStack );
-    return stack.identity;
-}
-
 status_t SharedBufferBase::getStatus() const
 {
     SharedBufferStack& stack( *mSharedStack );
     return stack.status;
 }
 
-size_t SharedBufferBase::getFrontBuffer() const
+int32_t SharedBufferBase::getIdentity() const
 {
     SharedBufferStack& stack( *mSharedStack );
-    return size_t( stack.head );
+    return stack.identity;
 }
 
 String8 SharedBufferBase::dump(char const* prefix) const
@@ -132,16 +197,52 @@
     char buffer[SIZE];
     String8 result;
     SharedBufferStack& stack( *mSharedStack );
-    int tail = (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
     snprintf(buffer, SIZE, 
-            "%s[ head=%2d, available=%2d, queued=%2d, tail=%2d ] "
-            "reallocMask=%08x, inUse=%2d, identity=%d, status=%d\n",
-            prefix, stack.head, stack.available, stack.queued, tail,
+            "%s[ head=%2d, available=%2d, queued=%2d ] "
+            "reallocMask=%08x, inUse=%2d, identity=%d, status=%d",
+            prefix, stack.head, stack.available, stack.queued,
             stack.reallocMask, stack.inUse, stack.identity, stack.status);
     result.append(buffer);
+    result.append("\n");
     return result;
 }
 
+status_t SharedBufferBase::waitForCondition(const ConditionBase& condition)
+{
+    const SharedBufferStack& stack( *mSharedStack );
+    SharedClient& client( *mSharedClient );
+    const nsecs_t TIMEOUT = s2ns(1);
+    const int identity = mIdentity;
+
+    Mutex::Autolock _l(client.lock);
+    while ((condition()==false) &&
+            (stack.identity == identity) &&
+            (stack.status == NO_ERROR))
+    {
+        status_t err = client.cv.waitRelative(client.lock, TIMEOUT);
+        // handle errors and timeouts
+        if (CC_UNLIKELY(err != NO_ERROR)) {
+            if (err == TIMED_OUT) {
+                if (condition()) {
+                    LOGE("waitForCondition(%s) timed out (identity=%d), "
+                        "but condition is true! We recovered but it "
+                        "shouldn't happen." , condition.name(), stack.identity);
+                    break;
+                } else {
+                    LOGW("waitForCondition(%s) timed out "
+                        "(identity=%d, status=%d). "
+                        "CPU may be pegged. trying again.", condition.name(),
+                        stack.identity, stack.status);
+                }
+            } else {
+                LOGE("waitForCondition(%s) error (%s) ",
+                        condition.name(), strerror(-err));
+                return err;
+            }
+        }
+    }
+    return (stack.identity != mIdentity) ? status_t(BAD_INDEX) : stack.status;
+}
 // ============================================================================
 // conditions and updates
 // ============================================================================
@@ -149,26 +250,21 @@
 SharedBufferClient::DequeueCondition::DequeueCondition(
         SharedBufferClient* sbc) : ConditionBase(sbc)  { 
 }
-bool SharedBufferClient::DequeueCondition::operator()() {
+bool SharedBufferClient::DequeueCondition::operator()() const {
     return stack.available > 0;
 }
 
 SharedBufferClient::LockCondition::LockCondition(
         SharedBufferClient* sbc, int buf) : ConditionBase(sbc), buf(buf) { 
 }
-bool SharedBufferClient::LockCondition::operator()() {
-    return (buf != stack.head || 
+bool SharedBufferClient::LockCondition::operator()() const {
+    // NOTE: if stack.head is messed up, we could crash the client
+    // or cause some drawing artifacts. This is okay, as long as it is
+    // limited to the client.
+    return (buf != stack.index[stack.head] ||
             (stack.queued > 0 && stack.inUse != buf));
 }
 
-SharedBufferServer::ReallocateCondition::ReallocateCondition(
-        SharedBufferBase* sbb, int buf) : ConditionBase(sbb), buf(buf) { 
-}
-bool SharedBufferServer::ReallocateCondition::operator()() {
-    // TODO: we should also check that buf has been dequeued
-    return (buf != stack.head);
-}
-
 // ----------------------------------------------------------------------------
 
 SharedBufferClient::QueueUpdate::QueueUpdate(SharedBufferBase* sbb)
@@ -179,6 +275,16 @@
     return NO_ERROR;
 }
 
+SharedBufferClient::DequeueUpdate::DequeueUpdate(SharedBufferBase* sbb)
+    : UpdateBase(sbb) {
+}
+ssize_t SharedBufferClient::DequeueUpdate::operator()() {
+    if (android_atomic_dec(&stack.available) == 0) {
+        LOGW("dequeue probably called from multiple threads!");
+    }
+    return NO_ERROR;
+}
+
 SharedBufferClient::UndoDequeueUpdate::UndoDequeueUpdate(SharedBufferBase* sbb)
     : UpdateBase(sbb) {    
 }
@@ -193,8 +299,10 @@
 }
 ssize_t SharedBufferServer::UnlockUpdate::operator()() {
     if (stack.inUse != lockedBuffer) {
-        LOGE("unlocking %d, but currently locked buffer is %d",
-                lockedBuffer, stack.inUse);
+        LOGE("unlocking %d, but currently locked buffer is %d "
+             "(identity=%d, token=%d)",
+                lockedBuffer, stack.inUse,
+                stack.identity, stack.token);
         return BAD_VALUE;
     }
     android_atomic_write(-1, &stack.inUse);
@@ -206,11 +314,12 @@
     : UpdateBase(sbb), numBuffers(numBuffers) {
 }
 ssize_t SharedBufferServer::RetireUpdate::operator()() {
-    // head is only written in this function, which is single-thread.
     int32_t head = stack.head;
+    if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
 
     // Preventively lock the current buffer before updating queued.
-    android_atomic_write(head, &stack.inUse);
+    android_atomic_write(stack.index[head], &stack.inUse);
 
     // Decrement the number of queued buffers 
     int32_t queued;
@@ -221,16 +330,15 @@
         }
     } while (android_atomic_cmpxchg(queued, queued-1, &stack.queued));
     
-    // update the head pointer
-    head = ((head+1 >= numBuffers) ? 0 : head+1);
-
     // lock the buffer before advancing head, which automatically unlocks
     // the buffer we preventively locked upon entering this function
-    android_atomic_write(head, &stack.inUse);
 
-    // advance head
+    head = (head + 1) % numBuffers;
+    android_atomic_write(stack.index[head], &stack.inUse);
+
+    // head is only modified here, so we don't need to use cmpxchg
     android_atomic_write(head, &stack.head);
-    
+
     // now that head has moved, we can increment the number of available buffers
     android_atomic_inc(&stack.available);
     return head;
@@ -250,41 +358,31 @@
 
 SharedBufferClient::SharedBufferClient(SharedClient* sharedClient,
         int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity), tail(0)
+    : SharedBufferBase(sharedClient, surface, identity),
+      mNumBuffers(num), tail(0), undoDequeueTail(0)
 {
+    SharedBufferStack& stack( *mSharedStack );
     tail = computeTail();
+    queued_head = stack.head;
 }
 
 int32_t SharedBufferClient::computeTail() const
 {
     SharedBufferStack& stack( *mSharedStack );
-    // we need to make sure we read available and head coherently,
-    // w.r.t RetireUpdate.
-    int32_t newTail;
-    int32_t avail;
-    int32_t head;
-    do {
-        avail = stack.available;
-        head = stack.head;
-    } while (stack.available != avail);
-    newTail = head - avail + 1;
-    if (newTail < 0) {
-        newTail += mNumBuffers;
-    } else if (newTail >= mNumBuffers) {
-        newTail -= mNumBuffers;
-    }
-    return newTail;
+    return (mNumBuffers + stack.head - stack.available + 1) % mNumBuffers;
 }
 
 ssize_t SharedBufferClient::dequeue()
 {
     SharedBufferStack& stack( *mSharedStack );
 
-    if (stack.head == tail && stack.available == 2) {
+    if (stack.head == tail && stack.available == mNumBuffers) {
         LOGW("dequeue: tail=%d, head=%d, avail=%d, queued=%d",
                 tail, stack.head, stack.available, stack.queued);
     }
-        
+
+    RWLock::AutoRLock _rd(mLock);
+
     const nsecs_t dequeueTime = systemTime(SYSTEM_TIME_THREAD);
 
     //LOGD("[%d] about to dequeue a buffer",
@@ -294,16 +392,13 @@
     if (err != NO_ERROR)
         return ssize_t(err);
 
-    // NOTE: 'stack.available' is part of the conditions, however
-    // decrementing it, never changes any conditions, so we don't need
-    // to do this as part of an update.
-    if (android_atomic_dec(&stack.available) == 0) {
-        LOGW("dequeue probably called from multiple threads!");
-    }
+    DequeueUpdate update(this);
+    updateCondition( update );
 
-    int dequeued = tail;
+    undoDequeueTail = tail;
+    int dequeued = stack.index[tail];
     tail = ((tail+1 >= mNumBuffers) ? 0 : tail+1);
-    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail=%d, %s",
+    LOGD_IF(DEBUG_ATOMICS, "dequeued=%d, tail++=%d, %s",
             dequeued, tail, dump("").string());
 
     mDequeueTime[dequeued] = dequeueTime; 
@@ -313,16 +408,23 @@
 
 status_t SharedBufferClient::undoDequeue(int buf)
 {
+    RWLock::AutoRLock _rd(mLock);
+
+    // TODO: we can only undo the previous dequeue, we should
+    // enforce that in the api
     UndoDequeueUpdate update(this);
     status_t err = updateCondition( update );
     if (err == NO_ERROR) {
-        tail = computeTail();
+        tail = undoDequeueTail;
     }
     return err;
 }
 
 status_t SharedBufferClient::lock(int buf)
 {
+    RWLock::AutoRLock _rd(mLock);
+
+    SharedBufferStack& stack( *mSharedStack );
     LockCondition condition(this, buf);
     status_t err = waitForCondition(condition);
     return err;
@@ -330,53 +432,111 @@
 
 status_t SharedBufferClient::queue(int buf)
 {
+    RWLock::AutoRLock _rd(mLock);
+
+    SharedBufferStack& stack( *mSharedStack );
+
+    queued_head = (queued_head + 1) % mNumBuffers;
+    stack.index[queued_head] = buf;
+
     QueueUpdate update(this);
     status_t err = updateCondition( update );
     LOGD_IF(DEBUG_ATOMICS, "queued=%d, %s", buf, dump("").string());
-    SharedBufferStack& stack( *mSharedStack );
+
     const nsecs_t now = systemTime(SYSTEM_TIME_THREAD);
     stack.stats.totalTime = ns2us(now - mDequeueTime[buf]);
     return err;
 }
 
-bool SharedBufferClient::needNewBuffer(int buffer) const
+bool SharedBufferClient::needNewBuffer(int buf) const
 {
     SharedBufferStack& stack( *mSharedStack );
-    const uint32_t mask = 1<<buffer;
+    const uint32_t mask = 1<<(31-buf);
     return (android_atomic_and(~mask, &stack.reallocMask) & mask) != 0;
 }
 
-status_t SharedBufferClient::setDirtyRegion(int buffer, const Region& reg)
+status_t SharedBufferClient::setCrop(int buf, const Rect& crop)
 {
     SharedBufferStack& stack( *mSharedStack );
-    return stack.setDirtyRegion(buffer, reg);
+    return stack.setCrop(buf, crop);
+}
+
+status_t SharedBufferClient::setTransform(int buf, uint32_t transform)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.setTransform(buf, uint8_t(transform));
+}
+
+status_t SharedBufferClient::setDirtyRegion(int buf, const Region& reg)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.setDirtyRegion(buf, reg);
+}
+
+status_t SharedBufferClient::setBufferCount(
+        int bufferCount, const SetBufferCountCallback& ipc)
+{
+    SharedBufferStack& stack( *mSharedStack );
+    if (uint32_t(bufferCount) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
+
+    if (uint32_t(bufferCount) < SharedBufferStack::NUM_BUFFER_MIN)
+        return BAD_VALUE;
+
+    RWLock::AutoWLock _wr(mLock);
+
+    status_t err = ipc(bufferCount);
+    if (err == NO_ERROR) {
+        mNumBuffers = bufferCount;
+        queued_head = (stack.head + stack.queued) % mNumBuffers;
+    }
+    return err;
 }
 
 // ----------------------------------------------------------------------------
 
 SharedBufferServer::SharedBufferServer(SharedClient* sharedClient,
         int surface, int num, int32_t identity)
-    : SharedBufferBase(sharedClient, surface, num, identity)
+    : SharedBufferBase(sharedClient, surface, identity),
+      mNumBuffers(num)
 {
     mSharedStack->init(identity);
+    mSharedStack->token = surface;
     mSharedStack->head = num-1;
     mSharedStack->available = num;
     mSharedStack->queued = 0;
     mSharedStack->reallocMask = 0;
-    memset(mSharedStack->dirtyRegion, 0, sizeof(mSharedStack->dirtyRegion));
+    memset(mSharedStack->buffers, 0, sizeof(mSharedStack->buffers));
+    for (int i=0 ; i<num ; i++) {
+        mBufferList.add(i);
+        mSharedStack->index[i] = i;
+    }
+}
+
+SharedBufferServer::~SharedBufferServer()
+{
 }
 
 ssize_t SharedBufferServer::retireAndLock()
 {
+    RWLock::AutoRLock _l(mLock);
+
     RetireUpdate update(this, mNumBuffers);
     ssize_t buf = updateCondition( update );
-    LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s", int(buf), dump("").string());
+    if (buf >= 0) {
+        if (uint32_t(buf) >= SharedBufferStack::NUM_BUFFER_MAX)
+            return BAD_VALUE;
+        SharedBufferStack& stack( *mSharedStack );
+        buf = stack.index[buf];
+        LOGD_IF(DEBUG_ATOMICS && buf>=0, "retire=%d, %s",
+                int(buf), dump("").string());
+    }
     return buf;
 }
 
-status_t SharedBufferServer::unlock(int buffer)
+status_t SharedBufferServer::unlock(int buf)
 {
-    UnlockUpdate update(this, buffer);
+    UnlockUpdate update(this, buf);
     status_t err = updateCondition( update );
     return err;
 }
@@ -389,11 +549,25 @@
     }
 }
 
-status_t SharedBufferServer::reallocate()
+status_t SharedBufferServer::reallocateAll()
 {
+    RWLock::AutoRLock _l(mLock);
+
     SharedBufferStack& stack( *mSharedStack );
-    uint32_t mask = (1<<mNumBuffers)-1;
-    android_atomic_or(mask, &stack.reallocMask); 
+    uint32_t mask = mBufferList.getMask();
+    android_atomic_or(mask, &stack.reallocMask);
+    return NO_ERROR;
+}
+
+status_t SharedBufferServer::reallocateAllExcept(int buffer)
+{
+    RWLock::AutoRLock _l(mLock);
+
+    SharedBufferStack& stack( *mSharedStack );
+    BufferList temp(mBufferList);
+    temp.remove(buffer);
+    uint32_t mask = temp.getMask();
+    android_atomic_or(mask, &stack.reallocMask);
     return NO_ERROR;
 }
 
@@ -403,17 +577,74 @@
     return stack.queued;
 }
 
-status_t SharedBufferServer::assertReallocate(int buffer)
-{
-    ReallocateCondition condition(this, buffer);
-    status_t err = waitForCondition(condition);
-    return err;
-}
-
-Region SharedBufferServer::getDirtyRegion(int buffer) const
+Region SharedBufferServer::getDirtyRegion(int buf) const
 {
     SharedBufferStack& stack( *mSharedStack );
-    return stack.getDirtyRegion(buffer);
+    return stack.getDirtyRegion(buf);
+}
+
+Rect SharedBufferServer::getCrop(int buf) const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.getCrop(buf);
+}
+
+uint32_t SharedBufferServer::getTransform(int buf) const
+{
+    SharedBufferStack& stack( *mSharedStack );
+    return stack.getTransform(buf);
+}
+
+/*
+ * NOTE: this is not thread-safe on the server-side, meaning
+ * 'head' cannot move during this operation. The client-side
+ * can safely operate an usual.
+ *
+ */
+status_t SharedBufferServer::resize(int newNumBuffers)
+{
+    if (uint32_t(newNumBuffers) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
+
+    RWLock::AutoWLock _l(mLock);
+
+    // for now we're not supporting shrinking
+    const int numBuffers = mNumBuffers;
+    if (newNumBuffers < numBuffers)
+        return BAD_VALUE;
+
+    SharedBufferStack& stack( *mSharedStack );
+    const int extra = newNumBuffers - numBuffers;
+
+    // read the head, make sure it's valid
+    int32_t head = stack.head;
+    if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
+        return BAD_VALUE;
+
+    int base = numBuffers;
+    int32_t avail = stack.available;
+    int tail = head - avail + 1;
+
+    if (tail >= 0) {
+        int8_t* const index = const_cast<int8_t*>(stack.index);
+        const int nb = numBuffers - head;
+        memmove(&index[head + extra], &index[head], nb);
+        base = head;
+        // move head 'extra' ahead, this doesn't impact stack.index[head];
+        stack.head = head + extra;
+    }
+    stack.available += extra;
+
+    // fill the new free space with unused buffers
+    BufferList::const_iterator curr(mBufferList.free_begin());
+    for (int i=0 ; i<extra ; i++) {
+        stack.index[base+i] = *curr;
+        mBufferList.add(*curr);
+        ++curr;
+    }
+
+    mNumBuffers = newNumBuffers;
+    return NO_ERROR;
 }
 
 SharedBufferStack::Statistics SharedBufferServer::getStats() const
@@ -422,6 +653,29 @@
     return stack.stats;
 }
 
+// ---------------------------------------------------------------------------
+status_t SharedBufferServer::BufferList::add(int value)
+{
+    if (uint32_t(value) >= mCapacity)
+        return BAD_VALUE;
+    uint32_t mask = 1<<(31-value);
+    if (mList & mask)
+        return ALREADY_EXISTS;
+    mList |= mask;
+    return NO_ERROR;
+}
+
+status_t SharedBufferServer::BufferList::remove(int value)
+{
+    if (uint32_t(value) >= mCapacity)
+        return BAD_VALUE;
+    uint32_t mask = 1<<(31-value);
+    if (!(mList & mask))
+        return NAME_NOT_FOUND;
+    mList &= ~mask;
+    return NO_ERROR;
+}
+
 
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index 5dd75c3..560ea67 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,180 @@
 //  Surface
 // ============================================================================
 
+class SurfaceClient : public Singleton<SurfaceClient>
+{
+    // all these attributes are constants
+    sp<ISurfaceComposer> mComposerService;
+    sp<ISurfaceComposerClient> mClient;
+    status_t mStatus;
+    SharedClient* mControl;
+    sp<IMemoryHeap> mControlMemory;
+
+    SurfaceClient()
+        : Singleton<SurfaceClient>(), mStatus(NO_INIT)
+    {
+        sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+        mComposerService = sf;
+        mClient = sf->createClientConnection();
+        if (mClient != NULL) {
+            mControlMemory = mClient->getControlBlock();
+            if (mControlMemory != NULL) {
+                mControl = static_cast<SharedClient *>(
+                        mControlMemory->getBase());
+                if (mControl) {
+                    mStatus = NO_ERROR;
+                }
+            }
+        }
+    }
+    friend class Singleton<SurfaceClient>;
+public:
+    status_t initCheck() const {
+        return mStatus;
+    }
+    SharedClient* getSharedClient() const {
+        return mControl;
+    }
+    ssize_t getTokenForSurface(const sp<ISurface>& sur) const {
+        // TODO: we could cache a few tokens here to avoid an IPC
+        return mClient->getTokenForSurface(sur);
+    }
+    void signalServer() const {
+        mComposerService->signal();
+    }
+};
+
+ANDROID_SINGLETON_STATIC_INSTANCE(SurfaceClient);
+
+// ---------------------------------------------------------------------------
+
 Surface::Surface(const sp<SurfaceControl>& surface)
-    : mClient(surface->mClient), mSurface(surface->mSurface),
-      mToken(surface->mToken), mIdentity(surface->mIdentity),
+    : mBufferMapper(GraphicBufferMapper::get()),
+      mClient(SurfaceClient::getInstance()),
+      mSharedBufferClient(NULL),
+      mInitCheck(NO_INIT),
+      mSurface(surface->mSurface),
+      mIdentity(surface->mIdentity),
       mFormat(surface->mFormat), mFlags(surface->mFlags),
-      mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL),
       mWidth(surface->mWidth), mHeight(surface->mHeight)
 {
-    mSharedBufferClient = new SharedBufferClient(
-            mClient->mControl, mToken, 2, mIdentity);
-
     init();
 }
 
-Surface::Surface(const Parcel& parcel)
-    :  mBufferMapper(GraphicBufferMapper::get()), mSharedBufferClient(NULL)
+Surface::Surface(const Parcel& parcel, const sp<IBinder>& ref)
+    : mBufferMapper(GraphicBufferMapper::get()),
+      mClient(SurfaceClient::getInstance()),
+      mSharedBufferClient(NULL),
+      mInitCheck(NO_INIT)
 {
-    sp<IBinder> clientBinder = parcel.readStrongBinder();
-    mSurface    = interface_cast<ISurface>(parcel.readStrongBinder());
-    mToken      = parcel.readInt32();
+    mSurface    = interface_cast<ISurface>(ref);
     mIdentity   = parcel.readInt32();
     mWidth      = parcel.readInt32();
     mHeight     = parcel.readInt32();
     mFormat     = parcel.readInt32();
     mFlags      = parcel.readInt32();
-
-    // FIXME: what does that mean if clientBinder is NULL here?
-    if (clientBinder != NULL) {
-        mClient = SurfaceComposerClient::clientForConnection(clientBinder);
-
-        mSharedBufferClient = new SharedBufferClient(
-                mClient->mControl, mToken, 2, mIdentity);
-    }
-
     init();
 }
 
+status_t Surface::writeToParcel(
+        const sp<Surface>& surface, Parcel* parcel)
+{
+    sp<ISurface> sur;
+    uint32_t identity = 0;
+    uint32_t width = 0;
+    uint32_t height = 0;
+    uint32_t format = 0;
+    uint32_t flags = 0;
+    if (Surface::isValid(surface)) {
+        sur      = surface->mSurface;
+        identity = surface->mIdentity;
+        width    = surface->mWidth;
+        height   = surface->mHeight;
+        format   = surface->mFormat;
+        flags    = surface->mFlags;
+    }
+    parcel->writeStrongBinder(sur!=0 ? sur->asBinder() : NULL);
+    parcel->writeInt32(identity);
+    parcel->writeInt32(width);
+    parcel->writeInt32(height);
+    parcel->writeInt32(format);
+    parcel->writeInt32(flags);
+    return NO_ERROR;
+
+}
+
+
+Mutex Surface::sCachedSurfacesLock;
+DefaultKeyedVector<wp<IBinder>, wp<Surface> > Surface::sCachedSurfaces(wp<Surface>(0));
+
+sp<Surface> Surface::readFromParcel(const Parcel& data) {
+    Mutex::Autolock _l(sCachedSurfacesLock);
+    sp<IBinder> binder(data.readStrongBinder());
+    sp<Surface> surface = sCachedSurfaces.valueFor(binder).promote();
+    if (surface == 0) {
+       surface = new Surface(data, binder);
+       sCachedSurfaces.add(binder, surface);
+    }
+    if (surface->mSurface == 0) {
+      surface = 0;
+    }
+    cleanCachedSurfaces();
+    return surface;
+}
+
+// Remove the stale entries from the surface cache.  This should only be called
+// with sCachedSurfacesLock held.
+void Surface::cleanCachedSurfaces() {
+    for (int i = sCachedSurfaces.size()-1; i >= 0; --i) {
+        wp<Surface> s(sCachedSurfaces.valueAt(i));
+        if (s == 0 || s.promote() == 0) {
+            sCachedSurfaces.removeItemsAt(i);
+        }
+    }
+}
+
 void Surface::init()
 {
-    android_native_window_t::setSwapInterval  = setSwapInterval;
-    android_native_window_t::dequeueBuffer    = dequeueBuffer;
-    android_native_window_t::lockBuffer       = lockBuffer;
-    android_native_window_t::queueBuffer      = queueBuffer;
-    android_native_window_t::query            = query;
-    android_native_window_t::perform          = perform;
-    mSwapRectangle.makeInvalid();
+    ANativeWindow::setSwapInterval  = setSwapInterval;
+    ANativeWindow::dequeueBuffer    = dequeueBuffer;
+    ANativeWindow::lockBuffer       = lockBuffer;
+    ANativeWindow::queueBuffer      = queueBuffer;
+    ANativeWindow::query            = query;
+    ANativeWindow::perform          = perform;
+
     DisplayInfo dinfo;
     SurfaceComposerClient::getDisplayInfo(0, &dinfo);
-    const_cast<float&>(android_native_window_t::xdpi) = dinfo.xdpi;
-    const_cast<float&>(android_native_window_t::ydpi) = dinfo.ydpi;
+    const_cast<float&>(ANativeWindow::xdpi) = dinfo.xdpi;
+    const_cast<float&>(ANativeWindow::ydpi) = dinfo.ydpi;
     // FIXME: set real values here
-    const_cast<int&>(android_native_window_t::minSwapInterval) = 1;
-    const_cast<int&>(android_native_window_t::maxSwapInterval) = 1;
-    const_cast<uint32_t&>(android_native_window_t::flags) = 0;
-    // be default we request a hardware surface
-    mUsage = GRALLOC_USAGE_HW_RENDER;
+    const_cast<int&>(ANativeWindow::minSwapInterval) = 1;
+    const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
+    const_cast<uint32_t&>(ANativeWindow::flags) = 0;
+
+    mNextBufferTransform = 0;
     mConnected = 0;
-    mNeedFullUpdate = false;
+    mSwapRectangle.makeInvalid();
+    mNextBufferCrop = Rect(0,0);
+    // two buffers by default
+    mBuffers.setCapacity(2);
+    mBuffers.insertAt(0, 2);
+
+    if (mSurface != 0 && mClient.initCheck() == NO_ERROR) {
+        int32_t token = mClient.getTokenForSurface(mSurface);
+        if (token >= 0) {
+            mSharedBufferClient = new SharedBufferClient(
+                    mClient.getSharedClient(), token, 2, mIdentity);
+            mInitCheck = mClient.getSharedClient()->validate(token);
+        }
+    }
 }
 
 Surface::~Surface()
 {
     // this is a client-side operation, the surface is destroyed, unmap
     // its buffers in this process.
-    for (int i=0 ; i<2 ; i++) {
+    size_t size = mBuffers.size();
+    for (size_t i=0 ; i<size ; i++) {
         if (mBuffers[i] != 0 && mBuffers[i]->handle != 0) {
             getBufferMapper().unregisterBuffer(mBuffers[i]->handle);
         }
@@ -369,93 +454,88 @@
 
     // clear all references and trigger an IPC now, to make sure things
     // happen without delay, since these resources are quite heavy.
-    mClient.clear();
+    mBuffers.clear();
     mSurface.clear();
     delete mSharedBufferClient;
     IPCThreadState::self()->flushCommands();
 }
 
-sp<SurfaceComposerClient> Surface::getClient() const {
-    return mClient;
+bool Surface::isValid() {
+    return mInitCheck == NO_ERROR;
+}
+
+status_t Surface::validate() const
+{
+    // check that we initialized ourself properly
+    if (mInitCheck != NO_ERROR) {
+        LOGE("invalid token (identity=%u)", mIdentity);
+        return mInitCheck;
+    }
+
+    // verify the identity of this surface
+    uint32_t identity = mSharedBufferClient->getIdentity();
+
+    // this is a bit of a (temporary) special case, identity==0 means that
+    // no operation are allowed from the client (eg: dequeue/queue), this
+    // is used with PUSH_BUFFER surfaces for instance
+    if (identity == 0) {
+        LOGE("[Surface] invalid operation (identity=%u)", mIdentity);
+        return INVALID_OPERATION;
+    }
+
+    if (mIdentity != identity) {
+        LOGE("[Surface] using an invalid surface, "
+                "identity=%u should be %d",
+                mIdentity, identity);
+        return NO_INIT;
+    }
+
+    // check the surface didn't become invalid
+    status_t err = mSharedBufferClient->getStatus();
+    if (err != NO_ERROR) {
+        LOGE("surface (identity=%u) is invalid, err=%d (%s)",
+                mIdentity, err, strerror(-err));
+        return err;
+    }
+
+    return NO_ERROR;
 }
 
 sp<ISurface> Surface::getISurface() const {
     return mSurface;
 }
 
-bool Surface::isValid() {
-    return mToken>=0 && mClient!=0;
-}
-
-status_t Surface::validate() const
-{
-    sp<SurfaceComposerClient> client(getClient());
-    if (mToken<0 || mClient==0) {
-        LOGE("invalid token (%d, identity=%u) or client (%p)", 
-                mToken, mIdentity, client.get());
-        return NO_INIT;
-    }
-    SharedClient const* cblk = mClient->mControl;
-    if (cblk == 0) {
-        LOGE("cblk is null (surface id=%d, identity=%u)", mToken, mIdentity);
-        return NO_INIT;
-    }
-    status_t err = cblk->validate(mToken);
-    if (err != NO_ERROR) {
-        LOGE("surface (id=%d, identity=%u) is invalid, err=%d (%s)",
-                mToken, mIdentity, err, strerror(-err));
-        return err;
-    }
-    uint32_t identity = cblk->getIdentity(mToken);
-    if (mIdentity != identity) {
-        LOGE("using an invalid surface id=%d, identity=%u should be %d",
-                mToken, mIdentity, identity);
-        return NO_INIT;
-    }
-    return NO_ERROR;
-}
-
-
-bool Surface::isSameSurface(
-        const sp<Surface>& lhs, const sp<Surface>& rhs) 
-{
-    if (lhs == 0 || rhs == 0)
-        return false;
-
-    return lhs->mSurface->asBinder() == rhs->mSurface->asBinder();
-}
-
 // ----------------------------------------------------------------------------
 
-int Surface::setSwapInterval(android_native_window_t* window, int interval) {
+int Surface::setSwapInterval(ANativeWindow* window, int interval) {
     return 0;
 }
 
-int Surface::dequeueBuffer(android_native_window_t* window, 
+int Surface::dequeueBuffer(ANativeWindow* window, 
         android_native_buffer_t** buffer) {
     Surface* self = getSelf(window);
     return self->dequeueBuffer(buffer);
 }
 
-int Surface::lockBuffer(android_native_window_t* window, 
+int Surface::lockBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer) {
     Surface* self = getSelf(window);
     return self->lockBuffer(buffer);
 }
 
-int Surface::queueBuffer(android_native_window_t* window, 
+int Surface::queueBuffer(ANativeWindow* window, 
         android_native_buffer_t* buffer) {
     Surface* self = getSelf(window);
     return self->queueBuffer(buffer);
 }
 
-int Surface::query(android_native_window_t* window, 
+int Surface::query(ANativeWindow* window, 
         int what, int* value) {
     Surface* self = getSelf(window);
     return self->query(what, value);
 }
 
-int Surface::perform(android_native_window_t* window, 
+int Surface::perform(ANativeWindow* window, 
         int operation, ...) {
     va_list args;
     va_start(args, operation);
@@ -467,49 +547,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;
     }
@@ -526,20 +619,25 @@
 
 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 +646,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 +681,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 +696,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 +727,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 +791,66 @@
     return err;
 }
 
-uint32_t Surface::getUsage() const
+int Surface::crop(Rect const* rect)
+{
+    // empty/invalid rects are not allowed
+    if (rect->isEmpty())
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mSurfaceLock);
+    // TODO: validate rect size
+    mNextBufferCrop = *rect;
+    return NO_ERROR;
+}
+
+int Surface::setBufferCount(int bufferCount)
+{
+    sp<ISurface> s(mSurface);
+    if (s == 0) return NO_INIT;
+
+    class SetBufferCountIPC : public SharedBufferClient::SetBufferCountCallback {
+        sp<ISurface> surface;
+        virtual status_t operator()(int bufferCount) const {
+            return surface->setBufferCount(bufferCount);
+        }
+    public:
+        SetBufferCountIPC(const sp<ISurface>& surface) : surface(surface) { }
+    } ipc(s);
+
+    status_t err = mSharedBufferClient->setBufferCount(bufferCount, ipc);
+    LOGE_IF(err, "ISurface::setBufferCount(%d) returned %s",
+            bufferCount, strerror(-err));
+    return err;
+}
+
+int Surface::setBuffersGeometry(int w, int h, int format)
+{
+    if (w<0 || h<0 || format<0)
+        return BAD_VALUE;
+
+    if ((w && !h) || (!w && h))
+        return BAD_VALUE;
+
+    Mutex::Autolock _l(mSurfaceLock);
+    mBufferInfo.set(w, h, format);
+    return NO_ERROR;
+}
+
+int Surface::setBuffersTransform(int transform)
 {
     Mutex::Autolock _l(mSurfaceLock);
-    return mUsage;
+    mNextBufferTransform = transform;
+    return NO_ERROR;
 }
 
+// ----------------------------------------------------------------------------
+
 int Surface::getConnectedApi() const
 {
     Mutex::Autolock _l(mSurfaceLock);
     return mConnected;
 }
 
-
 // ----------------------------------------------------------------------------
 
 status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -677,7 +861,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 +887,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 +963,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 +975,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 +989,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 +1013,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..4096ac6 100644
--- a/libs/surfaceflinger_client/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -17,98 +17,137 @@
 #define LOG_TAG "SurfaceComposerClient"
 
 #include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
 #include <sys/types.h>
-#include <sys/stat.h>
 
-#include <cutils/memory.h>
-
-#include <utils/Atomic.h>
 #include <utils/Errors.h>
 #include <utils/threads.h>
-#include <utils/KeyedVector.h>
+#include <utils/SortedVector.h>
 #include <utils/Log.h>
+#include <utils/Singleton.h>
 
 #include <binder/IServiceManager.h>
 #include <binder/IMemory.h>
 
 #include <ui/DisplayInfo.h>
-#include <ui/Rect.h>
 
 #include <surfaceflinger/ISurfaceComposer.h>
-#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurfaceComposerClient.h>
 #include <surfaceflinger/ISurface.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
 
 #include <private/surfaceflinger/LayerState.h>
 #include <private/surfaceflinger/SharedBufferStack.h>
 
-#define VERBOSE(...)	((void)0)
-//#define VERBOSE			LOGD
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
 namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE(ComposerService);
+
+ComposerService::ComposerService()
+: Singleton<ComposerService>() {
+    const String16 name("SurfaceFlinger");
+    while (getService(name, &mComposerService) != NO_ERROR) {
+        usleep(250000);
+    }
+    mServerCblkMemory = mComposerService->getCblk();
+    mServerCblk = static_cast<surface_flinger_cblk_t volatile *>(
+            mServerCblkMemory->getBase());
+}
+
+sp<ISurfaceComposer> ComposerService::getComposerService() {
+    return ComposerService::getInstance().mComposerService;
+}
+
+surface_flinger_cblk_t const volatile * ComposerService::getControlBlock() {
+    return ComposerService::getInstance().mServerCblk;
+}
+
+static inline sp<ISurfaceComposer> getComposerService() {
+    return ComposerService::getComposerService();
+}
+
+static inline surface_flinger_cblk_t const volatile * get_cblk() {
+    return ComposerService::getControlBlock();
+}
 
 // ---------------------------------------------------------------------------
 
-// Must not be holding SurfaceComposerClient::mLock when acquiring gLock here.
-static Mutex                                                gLock;
-static sp<ISurfaceComposer>                                 gSurfaceManager;
-static DefaultKeyedVector< sp<IBinder>, 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,20 @@
     matrix.dsdy = dsdy;
     matrix.dtdy = dtdy;
     s->matrix = matrix;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
 status_t SurfaceComposerClient::setFreezeTint(SurfaceID id, uint32_t tint)
 {
-    layer_state_t* s = _lockLayerState(id);
+    layer_state_t* s = lockLayerState(id);
     if (!s) return BAD_INDEX;
     s->what |= ISurfaceComposer::eFreezeTintChanged;
     s->tint = tint;
-    _unlockLayerState();
+    unlockLayerState();
     return NO_ERROR;
 }
 
+// ----------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/libs/surfaceflinger/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..1d38b4b 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 */
@@ -84,7 +86,7 @@
 
 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() {
@@ -97,6 +99,7 @@
     , mDevicesById(0), mNumDevicesById(0)
     , mOpeningDevices(0), mClosingDevices(0)
     , mDevices(0), mFDs(0), mFDCount(0), mOpened(false)
+    , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0)
 {
     acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
 #ifdef EV_SW
@@ -134,101 +137,71 @@
     return device->classes;
 }
 
-int EventHub::getAbsoluteInfo(int32_t deviceId, int axis, int *outMinValue,
-        int* outMaxValue, int* outFlat, int* outFuzz) const
-{
+status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis,
+        RawAbsoluteAxisInfo* outAxisInfo) const {
+    outAxisInfo->clear();
+
     AutoMutex _l(mLock);
     device_t* device = getDevice(deviceId);
     if (device == NULL) return -1;
 
     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 = getDevice(deviceId);
+        if (device != NULL) {
+            return getScanCodeStateLocked(device, scanCode);
         }
     }
-#endif
-    return -1;
+    return AKEY_STATE_UNKNOWN;
 }
 
-int EventHub::getSwitchState(int32_t deviceId, int sw) const
-{
-#ifdef EV_SW
-    AutoMutex _l(mLock);
-    device_t* device = getDevice(deviceId);
-    if (device == NULL) return -1;
-    
-    if (sw >= 0 && sw <= SW_MAX) {
-        uint8_t sw_bitmask[(SW_MAX+7)/8];
-        memset(sw_bitmask, 0, sizeof(sw_bitmask));
-        if (ioctl(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 = getDevice(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,12 +212,72 @@
             int32_t sc = scanCodes.itemAt(i);
             //LOGI("Code %d: down=%d", sc, test_bit(sc, key_bitmask));
             if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, key_bitmask)) {
-                return 1;
+                return AKEY_STATE_DOWN;
+            }
+        }
+        return AKEY_STATE_UP;
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const {
+#ifdef EV_SW
+    if (sw >= 0 && sw <= SW_MAX) {
+        AutoMutex _l(mLock);
+
+        device_t* device = getDevice(deviceId);
+        if (device != NULL) {
+            return getSwitchStateLocked(device, sw);
+        }
+    }
+#endif
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t EventHub::getSwitchStateLocked(device_t* device, int32_t sw) const {
+    uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
+    memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    if (ioctl(device->fd,
+               EVIOCGSW(sizeof(sw_bitmask)), sw_bitmask) >= 0) {
+        return test_bit(sw, sw_bitmask) ? AKEY_STATE_DOWN : AKEY_STATE_UP;
+    }
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) const {
+    AutoMutex _l(mLock);
+
+    device_t* device = getDevice(deviceId);
+    if (device != NULL) {
+        return markSupportedKeyCodesLocked(device, numCodes, keyCodes, outFlags);
+    }
+    return false;
+}
+
+bool EventHub::markSupportedKeyCodesLocked(device_t* device, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) const {
+    if (device->layoutMap == NULL || device->keyBitmask == NULL) {
+        return false;
+    }
+
+    Vector<int32_t> scanCodes;
+    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
+        scanCodes.clear();
+
+        status_t err = device->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
+        if (! err) {
+            // check the possible scan codes identified by the layout map against the
+            // map of codes actually emitted by the driver
+            for (size_t sc = 0; sc < scanCodes.size(); sc++) {
+                if (test_bit(scanCodes[sc], device->keyBitmask)) {
+                    outFlags[codeIndex] = 1;
+                    break;
+                }
             }
         }
     }
-    
-    return 0;
+    return true;
 }
 
 status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode,
@@ -295,27 +328,15 @@
     return NULL;
 }
 
-bool EventHub::getEvent(int32_t* outDeviceId, int32_t* outType,
-        int32_t* outScancode, int32_t* outKeycode, uint32_t *outFlags,
-        int32_t* outValue, nsecs_t* outWhen)
+bool EventHub::getEvent(RawEvent* outEvent)
 {
-    *outDeviceId = 0;
-    *outType = 0;
-    *outScancode = 0;
-    *outKeycode = 0;
-    *outFlags = 0;
-    *outValue = 0;
-    *outWhen = 0;
-
-    status_t err;
-
-    fd_set readfds;
-    int maxFd = -1;
-    int cc;
-    int i;
-    int res;
-    int pollres;
-    struct input_event iev;
+    outEvent->deviceId = 0;
+    outEvent->type = 0;
+    outEvent->scanCode = 0;
+    outEvent->keyCode = 0;
+    outEvent->flags = 0;
+    outEvent->value = 0;
+    outEvent->when = 0;
 
     // Note that we only allow one caller to getEvent(), so don't need
     // to do locking here...  only when adding/removing devices.
@@ -325,93 +346,127 @@
         mOpened = true;
     }
 
-    while(1) {
-
-        // First, report any devices that had last been added/removed.
+    for (;;) {
+        // Report any devices that had last been added/removed.
         if (mClosingDevices != NULL) {
             device_t* device = mClosingDevices;
             LOGV("Reporting device closed: id=0x%x, name=%s\n",
                  device->id, device->path.string());
             mClosingDevices = device->next;
-            *outDeviceId = device->id;
-            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
-            *outType = DEVICE_REMOVED;
+            if (device->id == mFirstKeyboardId) {
+                outEvent->deviceId = 0;
+            } else {
+                outEvent->deviceId = device->id;
+            }
+            outEvent->type = DEVICE_REMOVED;
             delete device;
             return true;
         }
+
         if (mOpeningDevices != NULL) {
             device_t* device = mOpeningDevices;
             LOGV("Reporting device opened: id=0x%x, name=%s\n",
                  device->id, device->path.string());
             mOpeningDevices = device->next;
-            *outDeviceId = device->id;
-            if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
-            *outType = DEVICE_ADDED;
+            if (device->id == mFirstKeyboardId) {
+                outEvent->deviceId = 0;
+            } else {
+                outEvent->deviceId = device->id;
+            }
+            outEvent->type = DEVICE_ADDED;
             return true;
         }
 
-        release_wake_lock(WAKE_LOCK_ID);
+        // Grab the next input event.
+        for (;;) {
+            // Consume buffered input events, if any.
+            if (mInputBufferIndex < mInputBufferCount) {
+                const struct input_event& iev = mInputBufferData[mInputBufferIndex++];
+                const device_t* device = mDevices[mInputDeviceIndex];
 
-        pollres = poll(mFDs, mFDCount, -1);
-
-        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
-
-        if (pollres <= 0) {
-            if (errno != EINTR) {
-                LOGW("select failed (errno=%d)\n", errno);
-                usleep(100000);
-            }
-            continue;
-        }
-
-        //printf("poll %d, returned %d\n", mFDCount, pollres);
-
-        // mFDs[0] is used for inotify, so process regular events starting at mFDs[1]
-        for(i = 1; i < mFDCount; i++) {
-            if(mFDs[i].revents) {
-                LOGV("revents for %d = 0x%08x", i, mFDs[i].revents);
-                if(mFDs[i].revents & POLLIN) {
-                    res = read(mFDs[i].fd, &iev, sizeof(iev));
-                    if (res == sizeof(iev)) {
-                        LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d",
-                             mDevices[i]->path.string(),
-                             (int) iev.time.tv_sec, (int) iev.time.tv_usec,
-                             iev.type, iev.code, iev.value);
-                        *outDeviceId = mDevices[i]->id;
-                        if (*outDeviceId == mFirstKeyboardId) *outDeviceId = 0;
-                        *outType = iev.type;
-                        *outScancode = iev.code;
-                        if (iev.type == EV_KEY) {
-                            err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);
-                            LOGV("iev.code=%d outKeycode=%d outFlags=0x%08x err=%d\n",
-                                iev.code, *outKeycode, *outFlags, err);
-                            if (err != 0) {
-                                *outKeycode = 0;
-                                *outFlags = 0;
-                            }
-                        } else {
-                            *outKeycode = iev.code;
-                        }
-                        *outValue = iev.value;
-                        *outWhen = s2ns(iev.time.tv_sec) + us2ns(iev.time.tv_usec);
-                        return true;
-                    } else {
-                        if (res<0) {
-                            LOGW("could not get event (errno=%d)", errno);
-                        } else {
-                            LOGE("could not get event (wrong size: %d)", res);
-                        }
-                        continue;
+                LOGV("%s got: t0=%d, t1=%d, type=%d, code=%d, v=%d", device->path.string(),
+                     (int) iev.time.tv_sec, (int) iev.time.tv_usec, iev.type, iev.code, iev.value);
+                if (device->id == mFirstKeyboardId) {
+                    outEvent->deviceId = 0;
+                } else {
+                    outEvent->deviceId = device->id;
+                }
+                outEvent->type = iev.type;
+                outEvent->scanCode = iev.code;
+                if (iev.type == EV_KEY) {
+                    status_t err = device->layoutMap->map(iev.code,
+                            & outEvent->keyCode, & outEvent->flags);
+                    LOGV("iev.code=%d keyCode=%d flags=0x%08x err=%d\n",
+                        iev.code, outEvent->keyCode, outEvent->flags, err);
+                    if (err != 0) {
+                        outEvent->keyCode = AKEYCODE_UNKNOWN;
+                        outEvent->flags = 0;
                     }
+                } else {
+                    outEvent->keyCode = iev.code;
+                }
+                outEvent->value = iev.value;
+
+                // Use an event timestamp in the same timebase as
+                // java.lang.System.nanoTime() and android.os.SystemClock.uptimeMillis()
+                // as expected by the rest of the system.
+                outEvent->when = systemTime(SYSTEM_TIME_MONOTONIC);
+                return true;
+            }
+
+            // Finish reading all events from devices identified in previous poll().
+            // This code assumes that mInputDeviceIndex is initially 0 and that the
+            // revents member of pollfd is initialized to 0 when the device is first added.
+            // Since mFDs[0] is used for inotify, we process regular events starting at index 1.
+            mInputDeviceIndex += 1;
+            if (mInputDeviceIndex >= mFDCount) {
+                mInputDeviceIndex = 0;
+                break;
+            }
+
+            const struct pollfd &pfd = mFDs[mInputDeviceIndex];
+            if (pfd.revents & POLLIN) {
+                int32_t readSize = read(pfd.fd, mInputBufferData,
+                        sizeof(struct input_event) * INPUT_BUFFER_SIZE);
+                if (readSize < 0) {
+                    if (errno != EAGAIN && errno != EINTR) {
+                        LOGW("could not get event (errno=%d)", errno);
+                    }
+                } else if ((readSize % sizeof(struct input_event)) != 0) {
+                    LOGE("could not get event (wrong size: %d)", readSize);
+                } else {
+                    mInputBufferCount = readSize / sizeof(struct input_event);
+                    mInputBufferIndex = 0;
                 }
             }
         }
-        
+
         // read_notify() will modify mFDs and mFDCount, so this must be done after
         // processing all other events.
         if(mFDs[0].revents & POLLIN) {
             read_notify(mFDs[0].fd);
         }
+
+        // Poll for events.  Mind the wake lock dance!
+        // We hold a wake lock at all times except during poll().  This works due to some
+        // subtle choreography.  When a device driver has pending (unread) events, it acquires
+        // a kernel wake lock.  However, once the last pending event has been read, the device
+        // driver will release the kernel wake lock.  To prevent the system from going to sleep
+        // when this happens, the EventHub holds onto its own user wake lock while the client
+        // is processing events.  Thus the system can only sleep if there are no events
+        // pending or currently being processed.
+        release_wake_lock(WAKE_LOCK_ID);
+
+        int pollResult = poll(mFDs, mFDCount, -1);
+
+        acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID);
+
+        if (pollResult <= 0) {
+            if (errno != EINTR) {
+                LOGW("select failed (errno=%d)\n", errno);
+                usleep(100000);
+            }
+        }
     }
 }
 
@@ -429,6 +484,7 @@
     mFDs = (pollfd *)calloc(1, sizeof(mFDs[0]));
     mDevices = (device_t **)calloc(1, sizeof(mDevices[0]));
     mFDs[0].events = POLLIN;
+    mFDs[0].revents = 0;
     mDevices[0] = NULL;
 #ifdef HAVE_INOTIFY
     mFDs[0].fd = inotify_init();
@@ -453,37 +509,27 @@
     return true;
 }
 
-/*
- * Inspect the known devices to determine whether physical keys exist for the given
- * framework-domain key codes.
- */
-bool EventHub::hasKeys(size_t numCodes, int32_t* keyCodes, uint8_t* outFlags) {
-    for (size_t codeIndex = 0; codeIndex < numCodes; codeIndex++) {
-        outFlags[codeIndex] = 0;
+// ----------------------------------------------------------------------------
 
-        // check each available hardware device for support for this keycode
-        Vector<int32_t> scanCodes;
-        for (int n = 0; (n < mFDCount) && (outFlags[codeIndex] == 0); n++) {
-            if (mDevices[n]) {
-                status_t err = mDevices[n]->layoutMap->findScancodes(keyCodes[codeIndex], &scanCodes);
-                if (!err) {
-                    // check the possible scan codes identified by the layout map against the
-                    // map of codes actually emitted by the driver
-                    for (size_t sc = 0; sc < scanCodes.size(); sc++) {
-                        if (test_bit(scanCodes[sc], mDevices[n]->keyBitmask)) {
-                            outFlags[codeIndex] = 1;
-                            break;
-                        }
-                    }
-                }
-            }
+static bool containsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex) {
+    const uint8_t* end = array + endIndex;
+    array += startIndex;
+    while (array != end) {
+        if (*(array++) != 0) {
+            return true;
         }
     }
-
-    return true;
+    return false;
 }
 
-// ----------------------------------------------------------------------------
+static const int32_t GAMEPAD_KEYCODES[] = {
+        AKEYCODE_BUTTON_A, AKEYCODE_BUTTON_B, AKEYCODE_BUTTON_C,
+        AKEYCODE_BUTTON_X, AKEYCODE_BUTTON_Y, AKEYCODE_BUTTON_Z,
+        AKEYCODE_BUTTON_L1, AKEYCODE_BUTTON_R1,
+        AKEYCODE_BUTTON_L2, AKEYCODE_BUTTON_R2,
+        AKEYCODE_BUTTON_THUMBL, AKEYCODE_BUTTON_THUMBR,
+        AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE
+};
 
 int EventHub::open_device(const char *deviceName)
 {
@@ -531,7 +577,6 @@
         if (strcmp(name, test) == 0) {
             LOGI("ignoring event id %s driver %s\n", deviceName, test);
             close(fd);
-            fd = -1;
             return -1;
         }
     }
@@ -545,6 +590,12 @@
         idstr[0] = '\0';
     }
 
+    if (fcntl(fd, F_SETFL, O_NONBLOCK)) {
+        LOGE("Error %d making device file descriptor non-blocking.", errno);
+        close(fd);
+        return -1;
+    }
+
     int devid = 0;
     while (devid < mNumDevicesById) {
         if (mDevicesById[devid].device == NULL) {
@@ -599,30 +650,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 +687,57 @@
         }
     }
     
-    // See if this is a trackball.
+    // See if this is a trackball (or mouse).
     if (test_bit(BTN_MOUSE, key_bitmask)) {
-        uint8_t rel_bitmask[(REL_MAX+7)/8];
+        uint8_t rel_bitmask[sizeof_bit_array(REL_MAX + 1)];
         memset(rel_bitmask, 0, sizeof(rel_bitmask));
         LOGV("Getting relative controllers...");
-        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0)
-        {
+        if (ioctl(fd, EVIOCGBIT(EV_REL, sizeof(rel_bitmask)), rel_bitmask) >= 0) {
             if (test_bit(REL_X, rel_bitmask) && test_bit(REL_Y, rel_bitmask)) {
-                device->classes |= CLASS_TRACKBALL;
+                device->classes |= INPUT_DEVICE_CLASS_TRACKBALL;
             }
         }
     }
-    
-    uint8_t abs_bitmask[(ABS_MAX+7)/8];
+
+    // See if this is a touch pad.
+    uint8_t abs_bitmask[sizeof_bit_array(ABS_MAX + 1)];
     memset(abs_bitmask, 0, sizeof(abs_bitmask));
     LOGV("Getting absolute controllers...");
-    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
-    
-    // Is this a new modern multi-touch driver?
-    if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
-            && test_bit(ABS_MT_POSITION_X, abs_bitmask)
-            && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
-        device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
-        
-    // Is this an old style single-touch driver?
-    } else if (test_bit(BTN_TOUCH, key_bitmask)
-            && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
-        device->classes |= CLASS_TOUCHSCREEN;
+    if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0) {
+        // Is this a new modern multi-touch driver?
+        if (test_bit(ABS_MT_POSITION_X, abs_bitmask)
+                && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN | INPUT_DEVICE_CLASS_TOUCHSCREEN_MT;
+
+        // Is this an old style single-touch driver?
+        } else if (test_bit(BTN_TOUCH, key_bitmask)
+                && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
+            device->classes |= INPUT_DEVICE_CLASS_TOUCHSCREEN;
+        }
     }
 
 #ifdef EV_SW
     // figure out the switches this device reports
-    uint8_t sw_bitmask[(SW_MAX+7)/8];
+    uint8_t sw_bitmask[sizeof_bit_array(SW_MAX + 1)];
     memset(sw_bitmask, 0, sizeof(sw_bitmask));
+    bool hasSwitches = false;
     if (ioctl(fd, EVIOCGBIT(EV_SW, sizeof(sw_bitmask)), sw_bitmask) >= 0) {
         for (int i=0; i<EV_SW; i++) {
             //LOGI("Device 0x%x sw %d: has=%d", device->id, i, test_bit(i, sw_bitmask));
             if (test_bit(i, sw_bitmask)) {
+                hasSwitches = true;
                 if (mSwitches[i] == 0) {
                     mSwitches[i] = device->id;
                 }
             }
         }
     }
+    if (hasSwitches) {
+        device->classes |= INPUT_DEVICE_CLASS_SWITCH;
+    }
 #endif
 
-    if ((device->classes&CLASS_KEYBOARD) != 0) {
+    if ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) {
         char tmpfn[sizeof(name)];
         char keylayoutFilename[300];
 
@@ -702,7 +759,10 @@
                      "%s/usr/keylayout/%s", root, "qwerty.kl");
             defaultKeymap = true;
         }
-        device->layoutMap->load(keylayoutFilename);
+        status_t status = device->layoutMap->load(keylayoutFilename);
+        if (status) {
+            LOGE("Error %d loading key layout.", status);
+        }
 
         // tell the world about the devname (the descriptive name)
         if (!mHaveFirstKeyboard && !defaultKeymap && strstr(name, "-keypad")) {
@@ -722,23 +782,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 (hasKeycode(device, AKEYCODE_Q)) {
+            device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY;
         }
         
-        // See if this has a DPAD.
-        if (hasKeycode(device, kKeyCodeDpadUp) &&
-                hasKeycode(device, kKeyCodeDpadDown) &&
-                hasKeycode(device, kKeyCodeDpadLeft) &&
-                hasKeycode(device, kKeyCodeDpadRight) &&
-                hasKeycode(device, kKeyCodeDpadCenter)) {
-            device->classes |= CLASS_DPAD;
+        // See if this device has a DPAD.
+        if (hasKeycode(device, AKEYCODE_DPAD_UP) &&
+                hasKeycode(device, AKEYCODE_DPAD_DOWN) &&
+                hasKeycode(device, AKEYCODE_DPAD_LEFT) &&
+                hasKeycode(device, AKEYCODE_DPAD_RIGHT) &&
+                hasKeycode(device, AKEYCODE_DPAD_CENTER)) {
+            device->classes |= INPUT_DEVICE_CLASS_DPAD;
         }
         
+        // See if this device has a gamepad.
+        for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES); i++) {
+            if (hasKeycode(device, GAMEPAD_KEYCODES[i])) {
+                device->classes |= INPUT_DEVICE_CLASS_GAMEPAD;
+                break;
+            }
+        }
+
         LOGI("New keyboard: device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
                 device->id, name, propName, keylayoutFilename);
     }
 
+    // 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);
          
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..1cf7592
--- /dev/null
+++ b/libs/ui/InputDispatcher.cpp
@@ -0,0 +1,3074 @@
+//
+// 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>
+
+namespace android {
+
+// Delay between reporting long touch events to the power manager.
+const nsecs_t EVENT_IGNORE_DURATION = 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";
+}
+
+
+// --- InputWindow ---
+
+bool InputWindow::visibleFrameIntersects(const InputWindow* other) const {
+    return visibleFrameRight > other->visibleFrameLeft
+        && visibleFrameLeft < other->visibleFrameRight
+        && visibleFrameBottom > other->visibleFrameTop
+        && visibleFrameTop < other->visibleFrameBottom;
+}
+
+bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
+    return x >= touchableAreaLeft && x <= touchableAreaRight
+            && y >= touchableAreaTop && y <= touchableAreaBottom;
+}
+
+
+// --- InputDispatcher ---
+
+InputDispatcher::InputDispatcher(const sp<InputDispatcherPolicyInterface>& policy) :
+    mPolicy(policy),
+    mPendingEvent(NULL), mAppSwitchDueTime(LONG_LONG_MAX),
+    mDispatchEnabled(true), mDispatchFrozen(false),
+    mFocusedWindow(NULL), mTouchDown(false), mTouchedWindow(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 disabled, drop all events in the queue.
+    if (! mDispatchEnabled) {
+        if (mPendingEvent || ! mInboundQueue.isEmpty()) {
+            LOGI("Dropping pending events because input dispatch is disabled.");
+            releasePendingEventLocked();
+            drainInboundQueueLocked();
+        }
+        return;
+    }
+
+    // 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) {
+                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;
+        }
+    }
+
+    // Now we have an event to dispatch.
+    assert(mPendingEvent != NULL);
+    bool done = false;
+    switch (mPendingEvent->type) {
+    case EventEntry::TYPE_CONFIGURATION_CHANGED: {
+        ConfigurationChangedEntry* typedEntry =
+                static_cast<ConfigurationChangedEntry*>(mPendingEvent);
+        done = dispatchConfigurationChangedLocked(currentTime, typedEntry);
+        break;
+    }
+
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* typedEntry = static_cast<KeyEntry*>(mPendingEvent);
+        bool appSwitchKey = isAppSwitchKey(typedEntry->keyCode);
+        bool dropEvent = isAppSwitchDue && ! appSwitchKey;
+        done = dispatchKeyLocked(currentTime, typedEntry, keyRepeatTimeout, dropEvent,
+                nextWakeupTime);
+        if (done) {
+            if (dropEvent) {
+                LOGI("Dropped key because of pending overdue app switch.");
+            } else if (appSwitchKey) {
+                resetPendingAppSwitchLocked(true);
+            }
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
+        bool dropEvent = isAppSwitchDue;
+        done = dispatchMotionLocked(currentTime, typedEntry, dropEvent, nextWakeupTime);
+        if (done) {
+            if (dropEvent) {
+                LOGI("Dropped motion because of pending overdue app switch.");
+            }
+        }
+        break;
+    }
+
+    default:
+        assert(false);
+        break;
+    }
+
+    if (done) {
+        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:
+        needWake |= detectPendingAppSwitchLocked(static_cast<KeyEntry*>(entry));
+        break;
+    }
+
+    return needWake;
+}
+
+bool InputDispatcher::isAppSwitchKey(int32_t keyCode) {
+    return keyCode == AKEYCODE_HOME || keyCode == AKEYCODE_ENDCALL;
+}
+
+bool InputDispatcher::isAppSwitchPendingLocked() {
+    return mAppSwitchDueTime != LONG_LONG_MAX;
+}
+
+bool InputDispatcher::detectPendingAppSwitchLocked(KeyEntry* inboundKeyEntry) {
+    if (inboundKeyEntry->action == AKEY_EVENT_ACTION_UP
+            && ! (inboundKeyEntry->flags & AKEY_EVENT_FLAG_CANCELED)
+            && isAppSwitchKey(inboundKeyEntry->keyCode)
+            && isEventFromReliableSourceLocked(inboundKeyEntry)) {
+#if DEBUG_APP_SWITCH
+        LOGD("App switch is pending!");
+#endif
+        mAppSwitchDueTime = inboundKeyEntry->eventTime + APP_SWITCH_TIMEOUT;
+        return true; // need wake
+    }
+    return false;
+}
+
+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) {
+    if (entry->injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+#if DEBUG_DISPATCH_CYCLE
+        LOGD("Inbound event was dropped.  Setting injection result to failed.");
+#endif
+        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+    }
+    mAllocator.releaseEventEntry(entry);
+}
+
+bool InputDispatcher::isEventFromReliableSourceLocked(EventEntry* entry) {
+    return ! entry->isInjected()
+            || entry->injectorUid == 0
+            || mPolicy->checkInjectEventsPermissionNonReentrant(
+                    entry->injectorPid, entry->injectorUid);
+}
+
+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;
+    if (entry->refCount == 1) {
+        entry->recycle();
+        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,
+        bool dropEvent, nsecs_t* nextWakeupTime) {
+    // Give the policy a chance to intercept the key.
+    if (entry->interceptKeyResult == KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN) {
+        bool trusted;
+        if (! dropEvent && mFocusedWindow) {
+            trusted = checkInjectionPermission(mFocusedWindow,
+                    entry->injectorPid, entry->injectorUid);
+        } else {
+            trusted = isEventFromReliableSourceLocked(entry);
+        }
+        if (trusted) {
+            CommandEntry* commandEntry = postCommandLocked(
+                    & InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible);
+            if (! dropEvent && 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) {
+        resetTargetsLocked();
+        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_SUCCEEDED);
+        return true;
+    }
+
+    // Clean up if dropping the event.
+    if (dropEvent) {
+        resetTargetsLocked();
+        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+        return true;
+    }
+
+    // Preprocessing.
+    if (! entry->dispatchInProgress) {
+        logOutboundKeyDetailsLocked("dispatchKey - ", entry);
+
+        if (entry->repeatCount == 0
+                && entry->action == AKEY_EVENT_ACTION_DOWN
+                && ! entry->isInjected()) {
+            if (mKeyRepeatState.lastKeyEntry
+                    && mKeyRepeatState.lastKeyEntry->keyCode == entry->keyCode) {
+                // We have seen two identical key downs in a row which indicates that the device
+                // driver is automatically generating key repeats itself.  We take note of the
+                // repeat here, but we disable our own next key repeat timer since it is clear that
+                // we will not need to synthesize key repeats ourselves.
+                entry->repeatCount = mKeyRepeatState.lastKeyEntry->repeatCount + 1;
+                resetKeyRepeatLocked();
+                mKeyRepeatState.nextRepeatTime = LONG_LONG_MAX; // don't generate repeats ourselves
+            } else {
+                // Not a repeat.  Save key down state in case we do see a repeat later.
+                resetKeyRepeatLocked();
+                mKeyRepeatState.nextRepeatTime = entry->eventTime + keyRepeatTimeout;
+            }
+            mKeyRepeatState.lastKeyEntry = entry;
+            entry->refCount += 1;
+        } else if (! entry->syntheticRepeat) {
+            resetKeyRepeatLocked();
+        }
+
+        entry->dispatchInProgress = true;
+        resetTargetsLocked();
+    }
+
+    // Identify targets.
+    if (! mCurrentInputTargetsValid) {
+        InputWindow* window = NULL;
+        int32_t injectionResult = findFocusedWindowLocked(currentTime,
+                entry, nextWakeupTime, & window);
+        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+            return false;
+        }
+
+        setInjectionResultLocked(entry, injectionResult);
+        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+            return true;
+        }
+
+        addMonitoringTargetsLocked();
+        commitTargetsLocked(window);
+    }
+
+    // Dispatch the key.
+    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+
+    // Poke user activity.
+    pokeUserActivityLocked(entry->eventTime, mCurrentInputWindowType, POWER_MANAGER_BUTTON_EVENT);
+    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, "
+            "downTime=%lld",
+            prefix,
+            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
+            entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
+            entry->downTime);
+#endif
+}
+
+bool InputDispatcher::dispatchMotionLocked(
+        nsecs_t currentTime, MotionEntry* entry, bool dropEvent, nsecs_t* nextWakeupTime) {
+    // Clean up if dropping the event.
+    if (dropEvent) {
+        resetTargetsLocked();
+        setInjectionResultLocked(entry, INPUT_EVENT_INJECTION_FAILED);
+        return true;
+    }
+
+    // Preprocessing.
+    if (! entry->dispatchInProgress) {
+        logOutboundMotionDetailsLocked("dispatchMotion - ", entry);
+
+        entry->dispatchInProgress = true;
+        resetTargetsLocked();
+    }
+
+    bool isPointerEvent = entry->source & AINPUT_SOURCE_CLASS_POINTER;
+
+    // Identify targets.
+    if (! mCurrentInputTargetsValid) {
+        InputWindow* window = NULL;
+        int32_t injectionResult;
+        if (isPointerEvent) {
+            // Pointer event.  (eg. touchscreen)
+            injectionResult = findTouchedWindowLocked(currentTime,
+                    entry, nextWakeupTime, & window);
+        } else {
+            // Non touch event.  (eg. trackball)
+            injectionResult = findFocusedWindowLocked(currentTime,
+                    entry, nextWakeupTime, & window);
+        }
+        if (injectionResult == INPUT_EVENT_INJECTION_PENDING) {
+            return false;
+        }
+
+        setInjectionResultLocked(entry, injectionResult);
+        if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+            return true;
+        }
+
+        addMonitoringTargetsLocked();
+        commitTargetsLocked(window);
+    }
+
+    // Dispatch the motion.
+    dispatchEventToCurrentInputTargetsLocked(currentTime, entry, false);
+
+    // Poke user activity.
+    int32_t eventType;
+    if (isPointerEvent) {
+        switch (entry->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 (entry->eventTime - entry->downTime >= EVENT_IGNORE_DURATION) {
+                eventType = POWER_MANAGER_TOUCH_EVENT;
+            } else {
+                eventType = POWER_MANAGER_LONG_TOUCH_EVENT;
+            }
+            break;
+        }
+    } else {
+        eventType = POWER_MANAGER_BUTTON_EVENT;
+    }
+    pokeUserActivityLocked(entry->eventTime, mCurrentInputWindowType, eventType);
+    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
+
+    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 {
+            LOGW("Framework requested delivery of an input event to channel '%s' but it "
+                    "is not registered with the input dispatcher.",
+                    inputTarget.inputChannel->getName().string());
+        }
+    }
+}
+
+void InputDispatcher::resetTargetsLocked() {
+    mCurrentInputTargetsValid = false;
+    mCurrentInputTargets.clear();
+    mCurrentInputChannel.clear();
+    mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_NONE;
+}
+
+void InputDispatcher::commitTargetsLocked(const InputWindow* window) {
+    mCurrentInputWindowType = window->layoutParamsType;
+    mCurrentInputChannel = window->inputChannel;
+    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 target.
+        releaseTouchedWindowLocked();
+
+        // 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);
+                connection->inputState.setOutOfSync();
+            }
+        }
+    }
+}
+
+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::findFocusedWindowLocked(nsecs_t currentTime, const EventEntry* entry,
+        nsecs_t* nextWakeupTime, InputWindow** outWindow) {
+    *outWindow = NULL;
+    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->injectorPid, entry->injectorUid)) {
+        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;
+    *outWindow = mFocusedWindow;
+    addWindowTargetLocked(mFocusedWindow, InputTarget::FLAG_FOREGROUND);
+
+    // 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::findTouchedWindowLocked(nsecs_t currentTime, const MotionEntry* entry,
+        nsecs_t* nextWakeupTime, InputWindow** outWindow) {
+    enum InjectionPermission {
+        INJECTION_PERMISSION_UNKNOWN,
+        INJECTION_PERMISSION_GRANTED,
+        INJECTION_PERMISSION_DENIED
+    };
+
+    *outWindow = NULL;
+    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;
+
+    // Update the touch state as needed based on the properties of the touch event.
+    int32_t injectionResult;
+    InjectionPermission injectionPermission;
+    if (action == AMOTION_EVENT_ACTION_DOWN) {
+        /* Case 1: ACTION_DOWN */
+
+        InputWindow* newTouchedWindow = NULL;
+        mTempTouchedOutsideTargets.clear();
+
+        int32_t x = int32_t(entry->firstSample.pointerCoords[0].x);
+        int32_t y = int32_t(entry->firstSample.pointerCoords[0].y);
+        InputWindow* topErrorWindow = NULL;
+        bool obscured = false;
+
+        // 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++) {
+            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;
+                            obscured = isWindowObscuredLocked(window);
+                        }
+                        break; // found touched window, exit window loop
+                    }
+                }
+
+                if (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH) {
+                    OutsideTarget outsideTarget;
+                    outsideTarget.window = window;
+                    outsideTarget.obscured = isWindowObscuredLocked(window);
+                    mTempTouchedOutsideTargets.push(outsideTarget);
+                }
+            }
+        }
+
+        // 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;
+        }
+
+        // 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);
+                injectionPermission = INJECTION_PERMISSION_UNKNOWN;
+                goto Unresponsive;
+            }
+
+            LOGI("Dropping event because there is no touched window or focused application.");
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
+            goto Failed;
+        }
+
+        // Check permissions.
+        if (! checkInjectionPermission(newTouchedWindow, entry->injectorPid, entry->injectorUid)) {
+            injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+            injectionPermission = INJECTION_PERMISSION_DENIED;
+            goto Failed;
+        }
+
+        // If the touched window is paused then keep waiting.
+        if (newTouchedWindow->paused) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+            LOGD("Waiting because touched window is paused.");
+#endif
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    NULL, newTouchedWindow, nextWakeupTime);
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+            goto Unresponsive;
+        }
+
+        // If the touched window is still working on previous events then keep waiting.
+        if (! isWindowFinishedWithPreviousInputLocked(newTouchedWindow)) {
+#if DEBUG_FOCUS
+            LOGD("Waiting because touched window still processing previous input.");
+#endif
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    NULL, newTouchedWindow, nextWakeupTime);
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+            goto Unresponsive;
+        }
+
+        // Success!  Update the touch dispatch state for real.
+        releaseTouchedWindowLocked();
+
+        mTouchedWindow = newTouchedWindow;
+        mTouchedWindowIsObscured = obscured;
+
+        if (newTouchedWindow->hasWallpaper) {
+            mTouchedWallpaperWindows.appendVector(mWallpaperWindows);
+        }
+    } else {
+        /* Case 2: Everything but ACTION_DOWN */
+
+        // Check permissions.
+        if (! checkInjectionPermission(mTouchedWindow, entry->injectorPid, entry->injectorUid)) {
+            injectionResult = INPUT_EVENT_INJECTION_PERMISSION_DENIED;
+            injectionPermission = INJECTION_PERMISSION_DENIED;
+            goto Failed;
+        }
+
+        // If the pointer is not currently down, then ignore the event.
+        if (! mTouchDown) {
+            LOGI("Dropping event because the pointer is not down.");
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+            goto Failed;
+        }
+
+        // If there is no currently touched window then fail.
+        if (! mTouchedWindow) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+            LOGD("Dropping event because there is no touched window to receive it.");
+#endif
+            injectionResult = INPUT_EVENT_INJECTION_FAILED;
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+            goto Failed;
+        }
+
+        // If the touched window is paused then keep waiting.
+        if (mTouchedWindow->paused) {
+#if DEBUG_INPUT_DISPATCHER_POLICY
+            LOGD("Waiting because touched window is paused.");
+#endif
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    NULL, mTouchedWindow, nextWakeupTime);
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+            goto Unresponsive;
+        }
+
+        // If the touched window is still working on previous events then keep waiting.
+        if (! isWindowFinishedWithPreviousInputLocked(mTouchedWindow)) {
+#if DEBUG_FOCUS
+            LOGD("Waiting because touched window still processing previous input.");
+#endif
+            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
+                    NULL, mTouchedWindow, nextWakeupTime);
+            injectionPermission = INJECTION_PERMISSION_GRANTED;
+            goto Unresponsive;
+        }
+    }
+
+    // Success!  Output targets.
+    injectionResult = INPUT_EVENT_INJECTION_SUCCEEDED;
+    injectionPermission = INJECTION_PERMISSION_GRANTED;
+
+    {
+        size_t numWallpaperWindows = mTouchedWallpaperWindows.size();
+        for (size_t i = 0; i < numWallpaperWindows; i++) {
+            addWindowTargetLocked(mTouchedWallpaperWindows[i],
+                    InputTarget::FLAG_WINDOW_IS_OBSCURED);
+        }
+
+        size_t numOutsideTargets = mTempTouchedOutsideTargets.size();
+        for (size_t i = 0; i < numOutsideTargets; i++) {
+            const OutsideTarget& outsideTarget = mTempTouchedOutsideTargets[i];
+            int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
+            if (outsideTarget.obscured) {
+                outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+            }
+            addWindowTargetLocked(outsideTarget.window, outsideTargetFlags);
+        }
+        mTempTouchedOutsideTargets.clear();
+
+        int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
+        if (mTouchedWindowIsObscured) {
+            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
+        }
+        addWindowTargetLocked(mTouchedWindow, targetFlags);
+        *outWindow = mTouchedWindow;
+    }
+
+Failed:
+    // Check injection permission once and for all.
+    if (injectionPermission == INJECTION_PERMISSION_UNKNOWN) {
+        if (checkInjectionPermission(action == AMOTION_EVENT_ACTION_DOWN ? NULL : mTouchedWindow,
+                entry->injectorPid, entry->injectorUid)) {
+            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 (action == AMOTION_EVENT_ACTION_DOWN) {
+            if (mTouchDown) {
+                // This is weird.  We got a down but we thought it was already down!
+                LOGW("Pointer down received while already down.");
+            } else {
+                mTouchDown = true;
+            }
+
+            if (injectionResult != INPUT_EVENT_INJECTION_SUCCEEDED) {
+                // Since we failed to identify a target for this touch down, we may still
+                // be holding on to an earlier target from a previous touch down.  Release it.
+                releaseTouchedWindowLocked();
+            }
+        } else if (action == AMOTION_EVENT_ACTION_UP) {
+            mTouchDown = false;
+            releaseTouchedWindowLocked();
+        }
+    } else {
+        LOGW("Not updating touch focus because injection was denied.");
+    }
+
+Unresponsive:
+    nsecs_t timeSpentWaitingForApplication = getTimeSpentWaitingForApplicationLocked(currentTime);
+    updateDispatchStatisticsLocked(currentTime, entry,
+            injectionResult, timeSpentWaitingForApplication);
+#if DEBUG_FOCUS
+    LOGD("findTouchedWindow finished: injectionResult=%d, injectionPermission=%d,"
+            "timeSpendWaitingForApplication=%0.1fms",
+            injectionResult, injectionPermission, timeSpentWaitingForApplication / 1000000.0);
+#endif
+    return injectionResult;
+}
+
+void InputDispatcher::releaseTouchedWindowLocked() {
+    mTouchedWindow = NULL;
+    mTouchedWindowIsObscured = false;
+    mTouchedWallpaperWindows.clear();
+}
+
+void InputDispatcher::addWindowTargetLocked(const InputWindow* window, int32_t targetFlags) {
+    mCurrentInputTargets.push();
+
+    InputTarget& target = mCurrentInputTargets.editTop();
+    target.inputChannel = window->inputChannel;
+    target.flags = targetFlags;
+    target.xOffset = - window->frameLeft;
+    target.yOffset = - window->frameTop;
+}
+
+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,
+        int32_t injectorPid, int32_t injectorUid) {
+    if (injectorUid > 0 && (window == NULL || window->ownerUid != injectorUid)) {
+        bool result = mPolicy->checkInjectEventsPermissionNonReentrant(injectorPid, injectorUid);
+        if (! result) {
+            if (window) {
+                LOGW("Permission denied: injecting event from pid %d uid %d to window "
+                        "with input channel %s owned by uid %d",
+                        injectorPid, injectorUid, window->inputChannel->getName().string(),
+                        window->ownerUid);
+            } else {
+                LOGW("Permission denied: injecting event from pid %d uid %d",
+                        injectorPid, injectorUid);
+            }
+            return false;
+        }
+    }
+    return true;
+}
+
+bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) {
+    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 && window->visibleFrameIntersects(other)) {
+            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(nsecs_t eventTime,
+        int32_t windowType, int32_t eventType) {
+    CommandEntry* commandEntry = postCommandLocked(
+            & InputDispatcher::doPokeUserActivityLockedInterruptible);
+    commandEntry->eventTime = eventTime;
+    commandEntry->windowType = windowType;
+    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, resumeWithAppendedMotionSample=%s",
+            connection->getInputChannelName(), inputTarget->flags,
+            inputTarget->xOffset, inputTarget->yOffset,
+            toString(resumeWithAppendedMotionSample));
+#endif
+
+    // 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) {
+        LOGW("channel '%s' ~ Dropping event because the channel status is %s",
+                connection->getInputChannelName(), connection->getStatusLabel());
+        return;
+    }
+
+    // Resume the dispatch cycle with a freshly appended motion sample.
+    // First we check that the last dispatch entry in the outbound queue is for the same
+    // motion event to which we appended the motion sample.  If we find such a dispatch
+    // entry, and if it is currently in progress then we try to stream the new sample.
+    bool wasEmpty = connection->outboundQueue.isEmpty();
+
+    if (! wasEmpty && resumeWithAppendedMotionSample) {
+        DispatchEntry* motionEventDispatchEntry =
+                connection->findQueuedDispatchEntryForEvent(eventEntry);
+        if (motionEventDispatchEntry) {
+            // If the dispatch entry is not in progress, then we must be busy dispatching an
+            // earlier event.  Not a problem, the motion event is on the outbound queue and will
+            // be dispatched later.
+            if (! motionEventDispatchEntry->inProgress) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Not streaming because the motion event has "
+                        "not yet been dispatched.  "
+                        "(Waiting for earlier events to be consumed.)",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+            // If the dispatch entry is in progress but it already has a tail of pending
+            // motion samples, then it must mean that the shared memory buffer filled up.
+            // Not a problem, when this dispatch cycle is finished, we will eventually start
+            // a new dispatch cycle to process the tail and that tail includes the newly
+            // appended motion sample.
+            if (motionEventDispatchEntry->tailMotionSample) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Not streaming because no new samples can "
+                        "be appended to the motion event in this dispatch cycle.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+            // The dispatch entry is in progress and is still potentially open for streaming.
+            // Try to stream the new motion sample.  This might fail if the consumer has already
+            // consumed the motion event (or if the channel is broken).
+            MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
+            status_t status = connection->inputPublisher.appendMotionSample(
+                    appendedMotionSample->eventTime, appendedMotionSample->pointerCoords);
+            if (status == OK) {
+#if DEBUG_BATCHING
+                LOGD("channel '%s' ~ Successfully streamed new motion sample.",
+                        connection->getInputChannelName());
+#endif
+                return;
+            }
+
+#if DEBUG_BATCHING
+            if (status == NO_MEMORY) {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event because the shared memory buffer is full.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+            } else if (status == status_t(FAILED_TRANSACTION)) {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event because the event has already been consumed.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName());
+            } else {
+                LOGD("channel '%s' ~ Could not append motion sample to currently "
+                        "dispatched move event due to an error, status=%d.  "
+                        "(Waiting for next dispatch cycle to start.)",
+                        connection->getInputChannelName(), status);
+            }
+#endif
+            // Failed to stream.  Start a new tail of pending motion samples to dispatch
+            // in the next cycle.
+            motionEventDispatchEntry->tailMotionSample = appendedMotionSample;
+            return;
+        }
+    }
+
+    // Bring the input state back in line with reality in case it drifted off during an ANR.
+    if (connection->inputState.isOutOfSync()) {
+        mTempCancelationEvents.clear();
+        connection->inputState.synthesizeCancelationEvents(& mAllocator, mTempCancelationEvents);
+        connection->inputState.resetOutOfSync();
+
+        if (! mTempCancelationEvents.isEmpty()) {
+            LOGI("channel '%s' ~ Generated %d cancelation events to bring channel back in sync "
+                    "with reality.",
+                    connection->getInputChannelName(), mTempCancelationEvents.size());
+
+            for (size_t i = 0; i < mTempCancelationEvents.size(); i++) {
+                EventEntry* cancelationEventEntry = mTempCancelationEvents.itemAt(i);
+                switch (cancelationEventEntry->type) {
+                case EventEntry::TYPE_KEY:
+                    logOutboundKeyDetailsLocked("  ",
+                            static_cast<KeyEntry*>(cancelationEventEntry));
+                    break;
+                case EventEntry::TYPE_MOTION:
+                    logOutboundMotionDetailsLocked("  ",
+                            static_cast<MotionEntry*>(cancelationEventEntry));
+                    break;
+                }
+
+                DispatchEntry* cancelationDispatchEntry =
+                        mAllocator.obtainDispatchEntry(cancelationEventEntry,
+                        0, inputTarget->xOffset, inputTarget->yOffset); // increments ref
+                connection->outboundQueue.enqueueAtTail(cancelationDispatchEntry);
+
+                mAllocator.releaseEventEntry(cancelationEventEntry);
+            }
+        }
+    }
+
+    // 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()) {
+        eventEntry->pendingForegroundDispatches += 1;
+    }
+
+    // Handle the case where we could not stream a new motion sample because the consumer has
+    // already consumed the motion event (otherwise the corresponding dispatch entry would
+    // still be in the outbound queue for this connection).  We set the head motion sample
+    // to the list starting with the newly appended motion sample.
+    if (resumeWithAppendedMotionSample) {
+#if DEBUG_BATCHING
+        LOGD("channel '%s' ~ Preparing a new dispatch cycle for additional motion samples "
+                "that cannot be streamed because the motion event has already been consumed.",
+                connection->getInputChannelName());
+#endif
+        MotionSample* appendedMotionSample = static_cast<MotionEntry*>(eventEntry)->lastSample;
+        dispatchEntry->headMotionSample = appendedMotionSample;
+    }
+
+    // Enqueue the dispatch entry.
+    connection->outboundQueue.enqueueAtTail(dispatchEntry);
+
+    // If the outbound queue was previously empty, start the dispatch cycle going.
+    if (wasEmpty) {
+        activateConnectionLocked(connection.get());
+        startDispatchCycleLocked(currentTime, connection);
+    }
+}
+
+void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ startDispatchCycle",
+            connection->getInputChannelName());
+#endif
+
+    assert(connection->status == Connection::STATUS_NORMAL);
+    assert(! connection->outboundQueue.isEmpty());
+
+    DispatchEntry* dispatchEntry = connection->outboundQueue.headSentinel.next;
+    assert(! dispatchEntry->inProgress);
+
+    // Mark the dispatch entry as in progress.
+    dispatchEntry->inProgress = true;
+
+    // Update the connection's input state.
+    InputState::Consistency consistency = connection->inputState.trackEvent(
+            dispatchEntry->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 (dispatchEntry->eventEntry->type) {
+    case EventEntry::TYPE_KEY: {
+        KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
+
+        // Apply target flags.
+        int32_t action = keyEntry->action;
+        int32_t flags = keyEntry->flags;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
+            flags |= AKEY_EVENT_FLAG_CANCELED;
+        }
+
+        // Publish the key event.
+        status = connection->inputPublisher.publishKeyEvent(keyEntry->deviceId, keyEntry->source,
+                action, flags, keyEntry->keyCode, keyEntry->scanCode,
+                keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
+                keyEntry->eventTime);
+
+        if (status) {
+            LOGE("channel '%s' ~ Could not publish key event, "
+                    "status=%d", connection->getInputChannelName(), status);
+            abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            return;
+        }
+        break;
+    }
+
+    case EventEntry::TYPE_MOTION: {
+        MotionEntry* motionEntry = static_cast<MotionEntry*>(dispatchEntry->eventEntry);
+
+        // Apply target flags.
+        int32_t action = motionEntry->action;
+        int32_t flags = motionEntry->flags;
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_OUTSIDE) {
+            action = AMOTION_EVENT_ACTION_OUTSIDE;
+        }
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_CANCEL) {
+            action = AMOTION_EVENT_ACTION_CANCEL;
+        }
+        if (dispatchEntry->targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) {
+            flags |= AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+        }
+
+        // If headMotionSample is non-NULL, then it points to the first new sample that we
+        // were unable to dispatch during the previous cycle so we resume dispatching from
+        // that point in the list of motion samples.
+        // Otherwise, we just start from the first sample of the motion event.
+        MotionSample* firstMotionSample = dispatchEntry->headMotionSample;
+        if (! firstMotionSample) {
+            firstMotionSample = & motionEntry->firstSample;
+        }
+
+        // Set the X and Y offset depending on the input source.
+        float xOffset, yOffset;
+        if (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) {
+            xOffset = dispatchEntry->xOffset;
+            yOffset = dispatchEntry->yOffset;
+        } else {
+            xOffset = 0.0f;
+            yOffset = 0.0f;
+        }
+
+        // Publish the motion event and the first motion sample.
+        status = connection->inputPublisher.publishMotionEvent(motionEntry->deviceId,
+                motionEntry->source, action, flags, motionEntry->edgeFlags, motionEntry->metaState,
+                xOffset, yOffset,
+                motionEntry->xPrecision, motionEntry->yPrecision,
+                motionEntry->downTime, firstMotionSample->eventTime,
+                motionEntry->pointerCount, motionEntry->pointerIds,
+                firstMotionSample->pointerCoords);
+
+        if (status) {
+            LOGE("channel '%s' ~ Could not publish motion event, "
+                    "status=%d", connection->getInputChannelName(), status);
+            abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            return;
+        }
+
+        // Append additional motion samples.
+        MotionSample* nextMotionSample = firstMotionSample->next;
+        for (; nextMotionSample != NULL; nextMotionSample = nextMotionSample->next) {
+            status = connection->inputPublisher.appendMotionSample(
+                    nextMotionSample->eventTime, nextMotionSample->pointerCoords);
+            if (status == NO_MEMORY) {
+#if DEBUG_DISPATCH_CYCLE
+                    LOGD("channel '%s' ~ Shared memory buffer full.  Some motion samples will "
+                            "be sent in the next dispatch cycle.",
+                            connection->getInputChannelName());
+#endif
+                break;
+            }
+            if (status != OK) {
+                LOGE("channel '%s' ~ Could not append motion sample "
+                        "for a reason other than out of memory, status=%d",
+                        connection->getInputChannelName(), status);
+                abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+                return;
+            }
+        }
+
+        // Remember the next motion sample that we could not dispatch, in case we ran out
+        // of space in the shared memory buffer.
+        dispatchEntry->tailMotionSample = nextMotionSample;
+        break;
+    }
+
+    default: {
+        assert(false);
+    }
+    }
+
+    // Send the dispatch signal.
+    status = connection->inputPublisher.sendDispatchSignal();
+    if (status) {
+        LOGE("channel '%s' ~ Could not send dispatch signal, status=%d",
+                connection->getInputChannelName(), status);
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+        return;
+    }
+
+    // Record information about the newly started dispatch cycle.
+    connection->lastEventTime = dispatchEntry->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);
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+        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::abortDispatchCycleLocked(nsecs_t currentTime,
+        const sp<Connection>& connection, bool broken) {
+#if DEBUG_DISPATCH_CYCLE
+    LOGD("channel '%s' ~ abortDispatchCycle - broken=%s",
+            connection->getInputChannelName(), toString(broken));
+#endif
+
+    // Input state will no longer be realistic.
+    connection->inputState.setOutOfSync();
+
+    // Clear the outbound queue.
+    drainOutboundQueueLocked(connection.get());
+
+    // Handle the case where the connection appears to be unrecoverably broken.
+    // Ignore already broken or zombie connections.
+    if (broken) {
+        if (connection->status == Connection::STATUS_NORMAL) {
+            connection->status = Connection::STATUS_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->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            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->abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+            d->runCommandsLockedInterruptible();
+            return 0; // remove the callback
+        }
+
+        d->finishDispatchCycleLocked(currentTime, connection);
+        d->runCommandsLockedInterruptible();
+        return 1;
+    } // release lock
+}
+
+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
+
+    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
+
+    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) {
+                        // No motion event is being dispatched.
+                        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();
+    }
+}
+
+int32_t InputDispatcher::injectInputEvent(const InputEvent* event,
+        int32_t injectorPid, int32_t injectorUid, int32_t syncMode, int32_t timeoutMillis) {
+#if DEBUG_INBOUND_EVENT_DETAILS
+    LOGD("injectInputEvent - eventType=%d, injectorPid=%d, injectorUid=%d, "
+            "syncMode=%d, timeoutMillis=%d",
+            event->getType(), injectorPid, injectorUid, syncMode, timeoutMillis);
+#endif
+
+    nsecs_t endTime = now() + milliseconds_to_nanoseconds(timeoutMillis);
+
+    EventEntry* injectedEntry;
+    bool needWake;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        injectedEntry = createEntryFromInjectedInputEventLocked(event);
+        if (! injectedEntry) {
+            return INPUT_EVENT_INJECTION_FAILED;
+        }
+
+        injectedEntry->refCount += 1;
+        injectedEntry->injectorPid = injectorPid;
+        injectedEntry->injectorUid = injectorUid;
+
+        if (syncMode == INPUT_EVENT_INJECTION_SYNC_NONE) {
+            injectedEntry->injectionIsAsync = true;
+        }
+
+        needWake = enqueueInboundEventLocked(injectedEntry);
+    } // release lock
+
+    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 = injectedEntry->injectionResult;
+                if (injectionResult != INPUT_EVENT_INJECTION_PENDING) {
+                    break;
+                }
+
+                nsecs_t remainingTimeout = endTime - now();
+                if (remainingTimeout <= 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Timed out waiting for injection result "
+                            "to become available.");
+#endif
+                    injectionResult = INPUT_EVENT_INJECTION_TIMED_OUT;
+                    break;
+                }
+
+                mInjectionResultAvailableCondition.waitRelative(mLock, remainingTimeout);
+            }
+
+            if (injectionResult == INPUT_EVENT_INJECTION_SUCCEEDED
+                    && syncMode == INPUT_EVENT_INJECTION_SYNC_WAIT_FOR_FINISHED) {
+                while (injectedEntry->pendingForegroundDispatches != 0) {
+#if DEBUG_INJECTION
+                    LOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
+                            injectedEntry->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.releaseEventEntry(injectedEntry);
+    } // release lock
+
+#if DEBUG_INJECTION
+    LOGD("injectInputEvent - Finished with result %d.  "
+            "injectorPid=%d, injectorUid=%d",
+            injectionResult, injectorPid, injectorUid);
+#endif
+
+    return injectionResult;
+}
+
+void InputDispatcher::setInjectionResultLocked(EventEntry* entry, int32_t injectionResult) {
+    if (entry->isInjected()) {
+#if DEBUG_INJECTION
+        LOGD("Setting input event injection result to %d.  "
+                "injectorPid=%d, injectorUid=%d",
+                 injectionResult, entry->injectorPid, entry->injectorUid);
+#endif
+
+        if (entry->injectionIsAsync) {
+            // Log the outcome since the injector did not wait for the injection result.
+            switch (injectionResult) {
+            case INPUT_EVENT_INJECTION_SUCCEEDED:
+                LOGV("Asynchronous input event injection succeeded.");
+                break;
+            case INPUT_EVENT_INJECTION_FAILED:
+                LOGW("Asynchronous input event injection failed.");
+                break;
+            case INPUT_EVENT_INJECTION_PERMISSION_DENIED:
+                LOGW("Asynchronous input event injection permission denied.");
+                break;
+            case INPUT_EVENT_INJECTION_TIMED_OUT:
+                LOGW("Asynchronous input event injection timed out.");
+                break;
+            }
+        }
+
+        entry->injectionResult = injectionResult;
+        mInjectionResultAvailableCondition.broadcast();
+    }
+}
+
+void InputDispatcher::decrementPendingForegroundDispatchesLocked(EventEntry* entry) {
+    entry->pendingForegroundDispatches -= 1;
+
+    if (entry->isInjected() && entry->pendingForegroundDispatches == 0) {
+        mInjectionSyncFinishedCondition.broadcast();
+    }
+}
+
+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 isValidMotionAction(int32_t action) {
+    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_POINTER_DOWN:
+    case AMOTION_EVENT_ACTION_POINTER_UP:
+    case AMOTION_EVENT_ACTION_OUTSIDE:
+        return true;
+    default:
+        return false;
+    }
+}
+
+InputDispatcher::EventEntry* InputDispatcher::createEntryFromInjectedInputEventLocked(
+        const InputEvent* event) {
+    switch (event->getType()) {
+    case AINPUT_EVENT_TYPE_KEY: {
+        const KeyEvent* keyEvent = static_cast<const KeyEvent*>(event);
+        if (! isValidKeyAction(keyEvent->getAction())) {
+            LOGE("Dropping injected key event since it has invalid action code 0x%x",
+                    keyEvent->getAction());
+            return NULL;
+        }
+
+        uint32_t policyFlags = POLICY_FLAG_INJECTED;
+
+        KeyEntry* keyEntry = mAllocator.obtainKeyEntry(keyEvent->getEventTime(),
+                keyEvent->getDeviceId(), keyEvent->getSource(), policyFlags,
+                keyEvent->getAction(), keyEvent->getFlags(),
+                keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
+                keyEvent->getRepeatCount(), keyEvent->getDownTime());
+        return keyEntry;
+    }
+
+    case AINPUT_EVENT_TYPE_MOTION: {
+        const MotionEvent* motionEvent = static_cast<const MotionEvent*>(event);
+        if (! isValidMotionAction(motionEvent->getAction())) {
+            LOGE("Dropping injected motion event since it has invalid action code 0x%x.",
+                    motionEvent->getAction());
+            return NULL;
+        }
+        if (motionEvent->getPointerCount() == 0
+                || motionEvent->getPointerCount() > MAX_POINTERS) {
+            LOGE("Dropping injected motion event since it has an invalid pointer count %d.",
+                    motionEvent->getPointerCount());
+        }
+
+        uint32_t policyFlags = POLICY_FLAG_INJECTED;
+
+        const nsecs_t* sampleEventTimes = motionEvent->getSampleEventTimes();
+        const PointerCoords* samplePointerCoords = motionEvent->getSamplePointerCoords();
+        size_t pointerCount = motionEvent->getPointerCount();
+
+        MotionEntry* motionEntry = mAllocator.obtainMotionEntry(*sampleEventTimes,
+                motionEvent->getDeviceId(), motionEvent->getSource(), policyFlags,
+                motionEvent->getAction(), motionEvent->getFlags(),
+                motionEvent->getMetaState(), motionEvent->getEdgeFlags(),
+                motionEvent->getXPrecision(), motionEvent->getYPrecision(),
+                motionEvent->getDownTime(), uint32_t(pointerCount),
+                motionEvent->getPointerIds(), samplePointerCoords);
+        for (size_t i = motionEvent->getHistorySize(); i > 0; i--) {
+            sampleEventTimes += 1;
+            samplePointerCoords += pointerCount;
+            mAllocator.appendMotionSample(motionEntry, *sampleEventTimes, samplePointerCoords);
+        }
+        return motionEntry;
+    }
+
+    default:
+        assert(false);
+        return NULL;
+    }
+}
+
+void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) {
+#if DEBUG_FOCUS
+    LOGD("setInputWindows");
+#endif
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Clear old window pointers but remember their associated channels.
+        mFocusedWindow = NULL;
+
+        sp<InputChannel> touchedWindowChannel;
+        if (mTouchedWindow) {
+            touchedWindowChannel = mTouchedWindow->inputChannel;
+            mTouchedWindow = NULL;
+        }
+        size_t numTouchedWallpapers = mTouchedWallpaperWindows.size();
+        if (numTouchedWallpapers != 0) {
+            for (size_t i = 0; i < numTouchedWallpapers; i++) {
+                mTempTouchedWallpaperChannels.push(mTouchedWallpaperWindows[i]->inputChannel);
+            }
+            mTouchedWallpaperWindows.clear();
+        }
+        mWallpaperWindows.clear();
+        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++) {
+            InputWindow* window = & mWindows.editItemAt(i);
+            if (window->hasFocus) {
+                mFocusedWindow = window;
+            }
+
+            if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
+                mWallpaperWindows.push(window);
+
+                for (size_t j = 0; j < numTouchedWallpapers; j++) {
+                    if (window->inputChannel == mTempTouchedWallpaperChannels[i]) {
+                        mTouchedWallpaperWindows.push(window);
+                    }
+                }
+            }
+
+            if (window->inputChannel == touchedWindowChannel) {
+                mTouchedWindow = window;
+            }
+        }
+        mTempTouchedWallpaperChannels.clear();
+
+#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();
+            }
+
+            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::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("  dispatchEnabled: %d\n", mDispatchEnabled);
+    dump.appendFormat("  dispatchFrozen: %d\n", mDispatchFrozen);
+
+    if (mFocusedApplication) {
+        dump.appendFormat("  focusedApplication: name='%s', dispatchingTimeout=%0.3fms\n",
+                mFocusedApplication->name.string(),
+                mFocusedApplication->dispatchingTimeout / 1000000.0);
+    } else {
+        dump.append("  focusedApplication: <null>\n");
+    }
+    dump.appendFormat("  focusedWindow: name='%s'\n",
+            mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>");
+    dump.appendFormat("  touchedWindow: name='%s', touchDown=%d\n",
+            mTouchedWindow != NULL ? mTouchedWindow->name.string() : "<null>",
+            mTouchDown);
+    for (size_t i = 0; i < mTouchedWallpaperWindows.size(); i++) {
+        dump.appendFormat("  touchedWallpaperWindows[%d]: name='%s'\n",
+                i, mTouchedWallpaperWindows[i]->name.string());
+    }
+    for (size_t i = 0; i < mWindows.size(); i++) {
+        dump.appendFormat("  windows[%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, mWindows[i].name.string(),
+                toString(mWindows[i].paused),
+                toString(mWindows[i].hasFocus),
+                toString(mWindows[i].hasWallpaper),
+                toString(mWindows[i].visible),
+                toString(mWindows[i].canReceiveKeys),
+                mWindows[i].layoutParamsFlags, mWindows[i].layoutParamsType,
+                mWindows[i].layer,
+                mWindows[i].frameLeft, mWindows[i].frameTop,
+                mWindows[i].frameRight, mWindows[i].frameBottom,
+                mWindows[i].visibleFrameLeft, mWindows[i].visibleFrameTop,
+                mWindows[i].visibleFrameRight, mWindows[i].visibleFrameBottom,
+                mWindows[i].touchableAreaLeft, mWindows[i].touchableAreaTop,
+                mWindows[i].touchableAreaRight, mWindows[i].touchableAreaBottom,
+                mWindows[i].ownerPid, mWindows[i].ownerUid,
+                mWindows[i].dispatchingTimeout / 1000000.0);
+    }
+
+    for (size_t i = 0; i < mMonitoringChannels.size(); i++) {
+        const sp<InputChannel>& channel = mMonitoringChannels[i];
+        dump.appendFormat("  monitoringChannel[%d]: '%s'\n",
+                i, channel->getName().string());
+    }
+
+    dump.appendFormat("  inboundQueue: length=%u", mInboundQueue.count());
+
+    for (size_t i = 0; i < mActiveConnections.size(); i++) {
+        const Connection* connection = mActiveConnections[i];
+        dump.appendFormat("  activeConnection[%d]: '%s', status=%s, outboundQueueLength=%u"
+                "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n",
+                i, connection->getInputChannelName(), connection->getStatusLabel(),
+                connection->outboundQueue.count(),
+                toString(connection->inputState.isNeutral()),
+                toString(connection->inputState.isOutOfSync()));
+    }
+
+    if (isAppSwitchPendingLocked()) {
+        dump.appendFormat("  appSwitch: pending, due in %01.1fms\n",
+                (mAppSwitchDueTime - now()) / 1000000.0);
+    } else {
+        dump.append("  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();
+        abortDispatchCycleLocked(currentTime, connection, true /*broken*/);
+
+        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->windowType,
+            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) {
+    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() {
+}
+
+void InputDispatcher::Allocator::initializeEventEntry(EventEntry* entry, int32_t type,
+        nsecs_t eventTime) {
+    entry->type = type;
+    entry->refCount = 1;
+    entry->dispatchInProgress = false;
+    entry->eventTime = eventTime;
+    entry->injectionResult = INPUT_EVENT_INJECTION_PENDING;
+    entry->injectionIsAsync = false;
+    entry->injectorPid = -1;
+    entry->injectorUid = -1;
+    entry->pendingForegroundDispatches = 0;
+}
+
+InputDispatcher::ConfigurationChangedEntry*
+InputDispatcher::Allocator::obtainConfigurationChangedEntry(nsecs_t eventTime) {
+    ConfigurationChangedEntry* entry = mConfigurationChangeEntryPool.alloc();
+    initializeEventEntry(entry, EventEntry::TYPE_CONFIGURATION_CHANGED, eventTime);
+    return entry;
+}
+
+InputDispatcher::KeyEntry* InputDispatcher::Allocator::obtainKeyEntry(nsecs_t eventTime,
+        int32_t deviceId, int32_t source, uint32_t policyFlags, int32_t action,
+        int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+        int32_t repeatCount, nsecs_t downTime) {
+    KeyEntry* entry = mKeyEntryPool.alloc();
+    initializeEventEntry(entry, EventEntry::TYPE_KEY, eventTime);
+
+    entry->deviceId = deviceId;
+    entry->source = source;
+    entry->policyFlags = policyFlags;
+    entry->action = action;
+    entry->flags = flags;
+    entry->keyCode = keyCode;
+    entry->scanCode = scanCode;
+    entry->metaState = metaState;
+    entry->repeatCount = repeatCount;
+    entry->downTime = downTime;
+    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);
+
+    entry->eventTime = eventTime;
+    entry->deviceId = deviceId;
+    entry->source = source;
+    entry->policyFlags = policyFlags;
+    entry->action = action;
+    entry->flags = flags;
+    entry->metaState = metaState;
+    entry->edgeFlags = edgeFlags;
+    entry->xPrecision = xPrecision;
+    entry->yPrecision = yPrecision;
+    entry->downTime = downTime;
+    entry->pointerCount = pointerCount;
+    entry->firstSample.eventTime = eventTime;
+    entry->firstSample.next = NULL;
+    entry->lastSample = & entry->firstSample;
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        entry->pointerIds[i] = pointerIds[i];
+        entry->firstSample.pointerCoords[i] = pointerCoords[i];
+    }
+    return entry;
+}
+
+InputDispatcher::DispatchEntry* InputDispatcher::Allocator::obtainDispatchEntry(
+        EventEntry* eventEntry,
+        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::releaseEventEntry(EventEntry* entry) {
+    switch (entry->type) {
+    case EventEntry::TYPE_CONFIGURATION_CHANGED:
+        releaseConfigurationChangedEntry(static_cast<ConfigurationChangedEntry*>(entry));
+        break;
+    case EventEntry::TYPE_KEY:
+        releaseKeyEntry(static_cast<KeyEntry*>(entry));
+        break;
+    case EventEntry::TYPE_MOTION:
+        releaseMotionEntry(static_cast<MotionEntry*>(entry));
+        break;
+    default:
+        assert(false);
+        break;
+    }
+}
+
+void InputDispatcher::Allocator::releaseConfigurationChangedEntry(
+        ConfigurationChangedEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        mConfigurationChangeEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseKeyEntry(KeyEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        mKeyEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseMotionEntry(MotionEntry* entry) {
+    entry->refCount -= 1;
+    if (entry->refCount == 0) {
+        for (MotionSample* sample = entry->firstSample.next; sample != NULL; ) {
+            MotionSample* next = sample->next;
+            mMotionSamplePool.free(sample);
+            sample = next;
+        }
+        mMotionEntryPool.free(entry);
+    } else {
+        assert(entry->refCount > 0);
+    }
+}
+
+void InputDispatcher::Allocator::releaseDispatchEntry(DispatchEntry* entry) {
+    releaseEventEntry(entry->eventEntry);
+    mDispatchEntryPool.free(entry);
+}
+
+void InputDispatcher::Allocator::releaseCommandEntry(CommandEntry* entry) {
+    mCommandEntryPool.free(entry);
+}
+
+void InputDispatcher::Allocator::appendMotionSample(MotionEntry* motionEntry,
+        nsecs_t eventTime, const PointerCoords* pointerCoords) {
+    MotionSample* sample = mMotionSamplePool.alloc();
+    sample->eventTime = eventTime;
+    uint32_t pointerCount = motionEntry->pointerCount;
+    for (uint32_t i = 0; i < pointerCount; i++) {
+        sample->pointerCoords[i] = pointerCoords[i];
+    }
+
+    sample->next = NULL;
+    motionEntry->lastSample->next = sample;
+    motionEntry->lastSample = sample;
+}
+
+
+// --- InputDispatcher::EventEntry ---
+
+void InputDispatcher::EventEntry::recycle() {
+    injectionResult = INPUT_EVENT_INJECTION_PENDING;
+    dispatchInProgress = false;
+    pendingForegroundDispatches = 0;
+}
+
+
+// --- InputDispatcher::KeyEntry ---
+
+void InputDispatcher::KeyEntry::recycle() {
+    EventEntry::recycle();
+    syntheticRepeat = false;
+    interceptKeyResult = 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() :
+        mIsOutOfSync(false) {
+}
+
+InputDispatcher::InputState::~InputState() {
+}
+
+bool InputDispatcher::InputState::isNeutral() const {
+    return mKeyMementos.isEmpty() && mMotionMementos.isEmpty();
+}
+
+bool InputDispatcher::InputState::isOutOfSync() const {
+    return mIsOutOfSync;
+}
+
+void InputDispatcher::InputState::setOutOfSync() {
+    if (! isNeutral()) {
+        mIsOutOfSync = true;
+    }
+}
+
+void InputDispatcher::InputState::resetOutOfSync() {
+    mIsOutOfSync = false;
+}
+
+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);
+                if (isNeutral()) {
+                    mIsOutOfSync = false;
+                }
+                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);
+                if (isNeutral()) {
+                    mIsOutOfSync = false;
+                }
+                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(
+        Allocator* allocator, Vector<EventEntry*>& outEvents) const {
+    for (size_t i = 0; i < mKeyMementos.size(); i++) {
+        const KeyMemento& memento = mKeyMementos.itemAt(i);
+        outEvents.push(allocator->obtainKeyEntry(now(),
+                memento.deviceId, memento.source, 0,
+                AKEY_EVENT_ACTION_UP, AKEY_EVENT_FLAG_CANCELED,
+                memento.keyCode, memento.scanCode, 0, 0, memento.downTime));
+    }
+
+    for (size_t i = 0; i < mMotionMementos.size(); i++) {
+        const MotionMemento& memento = mMotionMementos.itemAt(i);
+        outEvents.push(allocator->obtainMotionEntry(now(),
+                memento.deviceId, memento.source, 0,
+                AMOTION_EVENT_ACTION_CANCEL, 0, 0, 0,
+                memento.xPrecision, memento.yPrecision, memento.downTime,
+                memento.pointerCount, memento.pointerIds, memento.pointerCoords));
+    }
+}
+
+void InputDispatcher::InputState::clear() {
+    mKeyMementos.clear();
+    mMotionMementos.clear();
+    mIsOutOfSync = false;
+}
+
+
+// --- 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() {
+}
+
+
+// --- 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..783cbc4
--- /dev/null
+++ b/libs/ui/InputReader.cpp
@@ -0,0 +1,3408 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// The input reader.
+//
+#define LOG_TAG "InputReader"
+
+//#define LOG_NDEBUG 0
+
+// Log debug messages for each raw event received from the EventHub.
+#define DEBUG_RAW_EVENTS 0
+
+// Log debug messages about touch screen filtering hacks.
+#define DEBUG_HACKS 0
+
+// Log debug messages about virtual key processing.
+#define DEBUG_VIRTUAL_KEYS 0
+
+// Log debug messages about pointers.
+#define DEBUG_POINTERS 0
+
+// Log debug messages about pointer assignment calculations.
+#define DEBUG_POINTER_ASSIGNMENT 0
+
+#include <cutils/log.h>
+#include <ui/InputReader.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <math.h>
+
+#define INDENT "  "
+
+namespace android {
+
+// --- Static Functions ---
+
+template<typename T>
+inline static T abs(const T& value) {
+    return value < 0 ? - value : value;
+}
+
+template<typename T>
+inline static T min(const T& a, const T& b) {
+    return a < b ? a : b;
+}
+
+template<typename T>
+inline static void swap(T& a, T& b) {
+    T temp = a;
+    a = b;
+    b = temp;
+}
+
+inline static float avg(float x, float y) {
+    return (x + y) / 2;
+}
+
+inline static float pythag(float x, float y) {
+    return sqrtf(x * x + y * y);
+}
+
+
+int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState) {
+    int32_t mask;
+    switch (keyCode) {
+    case AKEYCODE_ALT_LEFT:
+        mask = AMETA_ALT_LEFT_ON;
+        break;
+    case AKEYCODE_ALT_RIGHT:
+        mask = AMETA_ALT_RIGHT_ON;
+        break;
+    case AKEYCODE_SHIFT_LEFT:
+        mask = AMETA_SHIFT_LEFT_ON;
+        break;
+    case AKEYCODE_SHIFT_RIGHT:
+        mask = AMETA_SHIFT_RIGHT_ON;
+        break;
+    case AKEYCODE_SYM:
+        mask = AMETA_SYM_ON;
+        break;
+    default:
+        return oldMetaState;
+    }
+
+    int32_t newMetaState = down ? oldMetaState | mask : oldMetaState & ~ mask
+            & ~ (AMETA_ALT_ON | AMETA_SHIFT_ON);
+
+    if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
+        newMetaState |= AMETA_ALT_ON;
+    }
+
+    if (newMetaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
+        newMetaState |= AMETA_SHIFT_ON;
+    }
+
+    return newMetaState;
+}
+
+static const int32_t keyCodeRotationMap[][4] = {
+        // key codes enumerated counter-clockwise with the original (unrotated) key first
+        // no rotation,        90 degree rotation,  180 degree rotation, 270 degree rotation
+        { AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT },
+        { AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN },
+        { AKEYCODE_DPAD_UP,     AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT },
+        { AKEYCODE_DPAD_LEFT,   AKEYCODE_DPAD_DOWN,   AKEYCODE_DPAD_RIGHT,  AKEYCODE_DPAD_UP },
+};
+static const int keyCodeRotationMapSize =
+        sizeof(keyCodeRotationMap) / sizeof(keyCodeRotationMap[0]);
+
+int32_t rotateKeyCode(int32_t keyCode, int32_t orientation) {
+    if (orientation != InputReaderPolicyInterface::ROTATION_0) {
+        for (int i = 0; i < keyCodeRotationMapSize; i++) {
+            if (keyCode == keyCodeRotationMap[i][0]) {
+                return keyCodeRotationMap[i][orientation];
+            }
+        }
+    }
+    return keyCode;
+}
+
+static inline bool sourcesMatchMask(uint32_t sources, uint32_t sourceMask) {
+    return (sources & sourceMask & ~ AINPUT_SOURCE_CLASS_MASK) != 0;
+}
+
+
+// --- InputDeviceCalibration ---
+
+InputDeviceCalibration::InputDeviceCalibration() {
+}
+
+void InputDeviceCalibration::clear() {
+    mProperties.clear();
+}
+
+void InputDeviceCalibration::addProperty(const String8& key, const String8& value) {
+    mProperties.add(key, value);
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, String8& outValue) const {
+    ssize_t index = mProperties.indexOfKey(key);
+    if (index < 0) {
+        return false;
+    }
+
+    outValue = mProperties.valueAt(index);
+    return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, int32_t& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    int value = strtol(stringValue.string(), & end, 10);
+    if (*end != '\0') {
+        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected an integer.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+bool InputDeviceCalibration::tryGetProperty(const String8& key, float& outValue) const {
+    String8 stringValue;
+    if (! tryGetProperty(key, stringValue) || stringValue.length() == 0) {
+        return false;
+    }
+
+    char* end;
+    float value = strtof(stringValue.string(), & end);
+    if (*end != '\0') {
+        LOGW("Input device calibration key '%s' has invalid value '%s'.  Expected a float.",
+                key.string(), stringValue.string());
+        return false;
+    }
+    outValue = value;
+    return true;
+}
+
+
+// --- InputReader ---
+
+InputReader::InputReader(const sp<EventHubInterface>& eventHub,
+        const sp<InputReaderPolicyInterface>& policy,
+        const sp<InputDispatcherInterface>& dispatcher) :
+        mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+        mGlobalMetaState(0) {
+    configureExcludedDevices();
+    updateGlobalMetaState();
+    updateInputConfiguration();
+}
+
+InputReader::~InputReader() {
+    for (size_t i = 0; i < mDevices.size(); i++) {
+        delete mDevices.valueAt(i);
+    }
+}
+
+void InputReader::loopOnce() {
+    RawEvent rawEvent;
+    mEventHub->getEvent(& rawEvent);
+
+#if DEBUG_RAW_EVENTS
+    LOGD("Input event: device=0x%x type=0x%x scancode=%d keycode=%d value=%d",
+            rawEvent.deviceId, rawEvent.type, rawEvent.scanCode, rawEvent.keyCode,
+            rawEvent.value);
+#endif
+
+    process(& rawEvent);
+}
+
+void InputReader::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EventHubInterface::DEVICE_ADDED:
+        addDevice(rawEvent->when, rawEvent->deviceId);
+        break;
+
+    case EventHubInterface::DEVICE_REMOVED:
+        removeDevice(rawEvent->when, rawEvent->deviceId);
+        break;
+
+    default:
+        consumeEvent(rawEvent);
+        break;
+    }
+}
+
+void InputReader::addDevice(nsecs_t when, int32_t deviceId) {
+    String8 name = mEventHub->getDeviceName(deviceId);
+    uint32_t classes = mEventHub->getDeviceClasses(deviceId);
+
+    // Write a log message about the added device as a heading for subsequent log messages.
+    LOGI("Device added: id=0x%x, name=%s", deviceId, name.string());
+
+    InputDevice* device = createDevice(deviceId, name, classes);
+    device->configure();
+
+    if (device->isIgnored()) {
+        LOGI(INDENT "Sources: none (device is ignored)");
+    } else {
+        LOGI(INDENT "Sources: 0x%08x", device->getSources());
+    }
+
+    bool added = false;
+    { // acquire device registry writer lock
+        RWLock::AutoWLock _wl(mDeviceRegistryLock);
+
+        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+        if (deviceIndex < 0) {
+            mDevices.add(deviceId, device);
+            added = true;
+        }
+    } // release device registry writer lock
+
+    if (! added) {
+        LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
+        delete device;
+        return;
+    }
+
+    handleConfigurationChanged(when);
+}
+
+void InputReader::removeDevice(nsecs_t when, int32_t deviceId) {
+    bool removed = false;
+    InputDevice* device = NULL;
+    { // acquire device registry writer lock
+        RWLock::AutoWLock _wl(mDeviceRegistryLock);
+
+        ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+        if (deviceIndex >= 0) {
+            device = mDevices.valueAt(deviceIndex);
+            mDevices.removeItemsAt(deviceIndex, 1);
+            removed = true;
+        }
+    } // release device registry writer lock
+
+    if (! removed) {
+        LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
+        return;
+    }
+
+    // Write a log message about the removed device as a heading for subsequent log messages.
+    if (device->isIgnored()) {
+        LOGI("Device removed: id=0x%x, name=%s (ignored non-input device)",
+                device->getId(), device->getName().string());
+    } else {
+        LOGI("Device removed: id=0x%x, name=%s, sources=%08x",
+                device->getId(), device->getName().string(), device->getSources());
+    }
+
+    device->reset();
+
+    delete device;
+
+    handleConfigurationChanged(when);
+}
+
+InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
+    InputDevice* device = new InputDevice(this, deviceId, name);
+
+    const int32_t associatedDisplayId = 0; // FIXME: hardcoded for current single-display devices
+
+    // Switch-like devices.
+    if (classes & INPUT_DEVICE_CLASS_SWITCH) {
+        device->addMapper(new SwitchInputMapper(device));
+    }
+
+    // Keyboard-like devices.
+    uint32_t keyboardSources = 0;
+    int32_t keyboardType = AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC;
+    if (classes & INPUT_DEVICE_CLASS_KEYBOARD) {
+        keyboardSources |= AINPUT_SOURCE_KEYBOARD;
+    }
+    if (classes & INPUT_DEVICE_CLASS_ALPHAKEY) {
+        keyboardType = AINPUT_KEYBOARD_TYPE_ALPHABETIC;
+    }
+    if (classes & INPUT_DEVICE_CLASS_DPAD) {
+        keyboardSources |= AINPUT_SOURCE_DPAD;
+    }
+
+    if (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) {
+    dumpDeviceInfo(dump);
+}
+
+static void dumpMotionRange(String8& dump,
+        const char* name, const InputDeviceInfo::MotionRange* range) {
+    if (range) {
+        dump.appendFormat("      %s = { min: %0.3f, max: %0.3f, flat: %0.3f, fuzz: %0.3f }\n",
+                name, range->min, range->max, range->flat, range->fuzz);
+    }
+}
+
+#define DUMP_MOTION_RANGE(range) \
+    dumpMotionRange(dump, #range, deviceInfo.getMotionRange(AINPUT_MOTION_RANGE_##range));
+
+void InputReader::dumpDeviceInfo(String8& dump) {
+    Vector<int32_t> deviceIds;
+    getInputDeviceIds(deviceIds);
+
+    InputDeviceInfo deviceInfo;
+    for (size_t i = 0; i < deviceIds.size(); i++) {
+        int32_t deviceId = deviceIds[i];
+
+        status_t result = getInputDeviceInfo(deviceId, & deviceInfo);
+        if (result == NAME_NOT_FOUND) {
+            continue;
+        } else if (result != OK) {
+            dump.appendFormat("  ** Unexpected error %d getting information about input devices.\n",
+                    result);
+            continue;
+        }
+
+        dump.appendFormat("  Device %d: '%s'\n",
+                deviceInfo.getId(), deviceInfo.getName().string());
+        dump.appendFormat("    sources = 0x%08x\n",
+                deviceInfo.getSources());
+        dump.appendFormat("    keyboardType = %d\n",
+                deviceInfo.getKeyboardType());
+
+        dump.append("    motion ranges:\n");
+        DUMP_MOTION_RANGE(X);
+        DUMP_MOTION_RANGE(Y);
+        DUMP_MOTION_RANGE(PRESSURE);
+        DUMP_MOTION_RANGE(SIZE);
+        DUMP_MOTION_RANGE(TOUCH_MAJOR);
+        DUMP_MOTION_RANGE(TOUCH_MINOR);
+        DUMP_MOTION_RANGE(TOOL_MAJOR);
+        DUMP_MOTION_RANGE(TOOL_MINOR);
+        DUMP_MOTION_RANGE(ORIENTATION);
+    }
+}
+
+#undef DUMP_MOTION_RANGE
+
+
+// --- InputReaderThread ---
+
+InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
+        Thread(/*canCallJava*/ true), mReader(reader) {
+}
+
+InputReaderThread::~InputReaderThread() {
+}
+
+bool InputReaderThread::threadLoop() {
+    mReader->loopOnce();
+    return true;
+}
+
+
+// --- InputDevice ---
+
+InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name) :
+        mContext(context), mId(id), mName(name), mSources(0) {
+}
+
+InputDevice::~InputDevice() {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        delete mMappers[i];
+    }
+    mMappers.clear();
+}
+
+void InputDevice::addMapper(InputMapper* mapper) {
+    mMappers.add(mapper);
+}
+
+void InputDevice::configure() {
+    if (! isIgnored()) {
+        mContext->getPolicy()->getInputDeviceCalibration(mName, mCalibration);
+    }
+
+    mSources = 0;
+
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->configure();
+        mSources |= mapper->getSources();
+    }
+}
+
+void InputDevice::reset() {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->reset();
+    }
+}
+
+void InputDevice::process(const RawEvent* rawEvent) {
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->process(rawEvent);
+    }
+}
+
+void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) {
+    outDeviceInfo->initialize(mId, mName);
+
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        mapper->populateDeviceInfo(outDeviceInfo);
+    }
+}
+
+int32_t InputDevice::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    return getState(sourceMask, keyCode, & InputMapper::getKeyCodeState);
+}
+
+int32_t InputDevice::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    return getState(sourceMask, scanCode, & InputMapper::getScanCodeState);
+}
+
+int32_t InputDevice::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return getState(sourceMask, switchCode, & InputMapper::getSwitchState);
+}
+
+int32_t InputDevice::getState(uint32_t sourceMask, int32_t code, GetStateFunc getStateFunc) {
+    int32_t result = AKEY_STATE_UNKNOWN;
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
+            result = (mapper->*getStateFunc)(sourceMask, code);
+            if (result >= AKEY_STATE_DOWN) {
+                return result;
+            }
+        }
+    }
+    return result;
+}
+
+bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    bool result = false;
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        if (sourcesMatchMask(mapper->getSources(), sourceMask)) {
+            result |= mapper->markSupportedKeyCodes(sourceMask, numCodes, keyCodes, outFlags);
+        }
+    }
+    return result;
+}
+
+int32_t InputDevice::getMetaState() {
+    int32_t result = 0;
+    size_t numMappers = mMappers.size();
+    for (size_t i = 0; i < numMappers; i++) {
+        InputMapper* mapper = mMappers[i];
+        result |= mapper->getMetaState();
+    }
+    return result;
+}
+
+
+// --- InputMapper ---
+
+InputMapper::InputMapper(InputDevice* device) :
+        mDevice(device), mContext(device->getContext()) {
+}
+
+InputMapper::~InputMapper() {
+}
+
+void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    info->addSource(getSources());
+}
+
+void InputMapper::configure() {
+}
+
+void InputMapper::reset() {
+}
+
+int32_t InputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t InputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t InputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool InputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    return false;
+}
+
+int32_t InputMapper::getMetaState() {
+    return 0;
+}
+
+bool InputMapper::applyStandardPolicyActions(nsecs_t when, int32_t policyActions) {
+    return policyActions & InputReaderPolicyInterface::ACTION_DISPATCH;
+}
+
+
+// --- SwitchInputMapper ---
+
+SwitchInputMapper::SwitchInputMapper(InputDevice* device) :
+        InputMapper(device) {
+}
+
+SwitchInputMapper::~SwitchInputMapper() {
+}
+
+uint32_t SwitchInputMapper::getSources() {
+    return 0;
+}
+
+void SwitchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_SW:
+        processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value);
+        break;
+    }
+}
+
+void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
+    uint32_t policyFlags = 0;
+    int32_t policyActions = getPolicy()->interceptSwitch(
+            when, switchCode, switchValue, policyFlags);
+
+    applyStandardPolicyActions(when, policyActions);
+}
+
+int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
+    return getEventHub()->getSwitchState(getDeviceId(), switchCode);
+}
+
+
+// --- KeyboardInputMapper ---
+
+KeyboardInputMapper::KeyboardInputMapper(InputDevice* device, int32_t associatedDisplayId,
+        uint32_t sources, int32_t keyboardType) :
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId), mSources(sources),
+        mKeyboardType(keyboardType) {
+    initializeLocked();
+}
+
+KeyboardInputMapper::~KeyboardInputMapper() {
+}
+
+void KeyboardInputMapper::initializeLocked() {
+    mLocked.metaState = AMETA_NONE;
+    mLocked.downTime = 0;
+}
+
+uint32_t KeyboardInputMapper::getSources() {
+    return mSources;
+}
+
+void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->setKeyboardType(mKeyboardType);
+}
+
+void KeyboardInputMapper::reset() {
+    for (;;) {
+        int32_t keyCode, scanCode;
+        { // acquire lock
+            AutoMutex _l(mLock);
+
+            // Synthesize key up event on reset if keys are currently down.
+            if (mLocked.keyDowns.isEmpty()) {
+                initializeLocked();
+                break; // done
+            }
+
+            const KeyDown& keyDown = mLocked.keyDowns.top();
+            keyCode = keyDown.keyCode;
+            scanCode = keyDown.scanCode;
+        } // release lock
+
+        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        processKey(when, false, keyCode, scanCode, 0);
+    }
+
+    InputMapper::reset();
+    getContext()->updateGlobalMetaState();
+}
+
+void KeyboardInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY: {
+        int32_t scanCode = rawEvent->scanCode;
+        if (isKeyboardOrGamepadKey(scanCode)) {
+            processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode,
+                    rawEvent->flags);
+        }
+        break;
+    }
+    }
+}
+
+bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
+    return scanCode < BTN_MOUSE
+        || scanCode >= KEY_OK
+        || (scanCode >= BTN_GAMEPAD && scanCode < BTN_DIGI);
+}
+
+void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
+        int32_t scanCode, uint32_t policyFlags) {
+    int32_t newMetaState;
+    nsecs_t downTime;
+    bool metaStateChanged = false;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (down) {
+            // Rotate key codes according to orientation if needed.
+            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+            if (mAssociatedDisplayId >= 0) {
+                int32_t orientation;
+                if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+                    return;
+                }
+
+                keyCode = rotateKeyCode(keyCode, orientation);
+            }
+
+            // Add key down.
+            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+            if (keyDownIndex >= 0) {
+                // key repeat, be sure to use same keycode as before in case of rotation
+                keyCode = mLocked.keyDowns.top().keyCode;
+            } else {
+                // key down
+                mLocked.keyDowns.push();
+                KeyDown& keyDown = mLocked.keyDowns.editTop();
+                keyDown.keyCode = keyCode;
+                keyDown.scanCode = scanCode;
+            }
+
+            mLocked.downTime = when;
+        } else {
+            // Remove key down.
+            ssize_t keyDownIndex = findKeyDownLocked(scanCode);
+            if (keyDownIndex >= 0) {
+                // key up, be sure to use same keycode as before in case of rotation
+                keyCode = mLocked.keyDowns.top().keyCode;
+                mLocked.keyDowns.removeAt(size_t(keyDownIndex));
+            } else {
+                // key was not actually down
+                LOGI("Dropping key up from device %s because the key was not down.  "
+                        "keyCode=%d, scanCode=%d",
+                        getDeviceName().string(), keyCode, scanCode);
+                return;
+            }
+        }
+
+        int32_t oldMetaState = mLocked.metaState;
+        newMetaState = updateMetaState(keyCode, down, oldMetaState);
+        if (oldMetaState != newMetaState) {
+            mLocked.metaState = newMetaState;
+            metaStateChanged = true;
+        }
+
+        downTime = mLocked.downTime;
+    } // release lock
+
+    if (metaStateChanged) {
+        getContext()->updateGlobalMetaState();
+    }
+
+    applyPolicyAndDispatch(when, policyFlags, down, keyCode, scanCode, newMetaState, downTime);
+}
+
+void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFlags, bool down,
+        int32_t keyCode, int32_t scanCode, int32_t metaState, nsecs_t downTime) {
+    int32_t policyActions = getPolicy()->interceptKey(when,
+            getDeviceId(), down, keyCode, scanCode, policyFlags);
+
+    if (! applyStandardPolicyActions(when, policyActions)) {
+        return; // event dropped
+    }
+
+    int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP;
+    int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM;
+    if (policyFlags & POLICY_FLAG_WOKE_HERE) {
+        keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE;
+    }
+
+    getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+}
+
+ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
+    size_t n = mLocked.keyDowns.size();
+    for (size_t i = 0; i < n; i++) {
+        if (mLocked.keyDowns[i].scanCode == scanCode) {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int32_t KeyboardInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    return getEventHub()->getKeyCodeState(getDeviceId(), keyCode);
+}
+
+int32_t KeyboardInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+}
+
+bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    return getEventHub()->markSupportedKeyCodes(getDeviceId(), numCodes, keyCodes, outFlags);
+}
+
+int32_t KeyboardInputMapper::getMetaState() {
+    { // acquire lock
+        AutoMutex _l(mLock);
+        return mLocked.metaState;
+    } // release lock
+}
+
+
+// --- TrackballInputMapper ---
+
+TrackballInputMapper::TrackballInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+    mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+    mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+    mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+    mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+
+    initializeLocked();
+}
+
+TrackballInputMapper::~TrackballInputMapper() {
+}
+
+uint32_t TrackballInputMapper::getSources() {
+    return AINPUT_SOURCE_TRACKBALL;
+}
+
+void TrackballInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    info->addMotionRange(AINPUT_MOTION_RANGE_X, -1.0f, 1.0f, 0.0f, mXScale);
+    info->addMotionRange(AINPUT_MOTION_RANGE_Y, -1.0f, 1.0f, 0.0f, mYScale);
+}
+
+void TrackballInputMapper::initializeLocked() {
+    mAccumulator.clear();
+
+    mLocked.down = false;
+    mLocked.downTime = 0;
+}
+
+void TrackballInputMapper::reset() {
+    for (;;) {
+        { // acquire lock
+            AutoMutex _l(mLock);
+
+            if (! mLocked.down) {
+                initializeLocked();
+                break; // done
+            }
+        } // release lock
+
+        // Synthesize trackball button up event on reset.
+        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        mAccumulator.fields = Accumulator::FIELD_BTN_MOUSE;
+        mAccumulator.btnMouse = false;
+        sync(when);
+    }
+
+    InputMapper::reset();
+}
+
+void TrackballInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY:
+        switch (rawEvent->scanCode) {
+        case BTN_MOUSE:
+            mAccumulator.fields |= Accumulator::FIELD_BTN_MOUSE;
+            mAccumulator.btnMouse = rawEvent->value != 0;
+            // Sync now since BTN_MOUSE is not necessarily followed by SYN_REPORT and
+            // we need to ensure that we report the up/down promptly.
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+
+    case EV_REL:
+        switch (rawEvent->scanCode) {
+        case REL_X:
+            mAccumulator.fields |= Accumulator::FIELD_REL_X;
+            mAccumulator.relX = rawEvent->value;
+            break;
+        case REL_Y:
+            mAccumulator.fields |= Accumulator::FIELD_REL_Y;
+            mAccumulator.relY = rawEvent->value;
+            break;
+        }
+        break;
+
+    case EV_SYN:
+        switch (rawEvent->scanCode) {
+        case SYN_REPORT:
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+    }
+}
+
+void TrackballInputMapper::sync(nsecs_t when) {
+    uint32_t fields = mAccumulator.fields;
+    if (fields == 0) {
+        return; // no new state changes, so nothing to do
+    }
+
+    int motionEventAction;
+    PointerCoords pointerCoords;
+    nsecs_t downTime;
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        bool downChanged = fields & Accumulator::FIELD_BTN_MOUSE;
+
+        if (downChanged) {
+            if (mAccumulator.btnMouse) {
+                mLocked.down = true;
+                mLocked.downTime = when;
+            } else {
+                mLocked.down = false;
+            }
+        }
+
+        downTime = mLocked.downTime;
+        float x = fields & Accumulator::FIELD_REL_X ? mAccumulator.relX * mXScale : 0.0f;
+        float y = fields & Accumulator::FIELD_REL_Y ? mAccumulator.relY * mYScale : 0.0f;
+
+        if (downChanged) {
+            motionEventAction = mLocked.down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+        } else {
+            motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+        }
+
+        pointerCoords.x = x;
+        pointerCoords.y = y;
+        pointerCoords.pressure = mLocked.down ? 1.0f : 0.0f;
+        pointerCoords.size = 0;
+        pointerCoords.touchMajor = 0;
+        pointerCoords.touchMinor = 0;
+        pointerCoords.toolMajor = 0;
+        pointerCoords.toolMinor = 0;
+        pointerCoords.orientation = 0;
+
+        if (mAssociatedDisplayId >= 0 && (x != 0.0f || y != 0.0f)) {
+            // Rotate motion based on display orientation if needed.
+            // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+            int32_t orientation;
+            if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, NULL, NULL, & orientation)) {
+                return;
+            }
+
+            float temp;
+            switch (orientation) {
+            case InputReaderPolicyInterface::ROTATION_90:
+                temp = pointerCoords.x;
+                pointerCoords.x = pointerCoords.y;
+                pointerCoords.y = - temp;
+                break;
+
+            case InputReaderPolicyInterface::ROTATION_180:
+                pointerCoords.x = - pointerCoords.x;
+                pointerCoords.y = - pointerCoords.y;
+                break;
+
+            case InputReaderPolicyInterface::ROTATION_270:
+                temp = pointerCoords.x;
+                pointerCoords.x = - pointerCoords.y;
+                pointerCoords.y = temp;
+                break;
+            }
+        }
+    } // release lock
+
+    applyPolicyAndDispatch(when, motionEventAction, & pointerCoords, downTime);
+
+    mAccumulator.clear();
+}
+
+void TrackballInputMapper::applyPolicyAndDispatch(nsecs_t when, int32_t motionEventAction,
+        PointerCoords* pointerCoords, nsecs_t downTime) {
+    uint32_t policyFlags = 0;
+    int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
+
+    if (! applyStandardPolicyActions(when, policyActions)) {
+        return; // event dropped
+    }
+
+    int32_t metaState = mContext->getGlobalMetaState();
+    int32_t pointerId = 0;
+
+    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TRACKBALL, policyFlags,
+            motionEventAction, 0, metaState, AMOTION_EVENT_EDGE_FLAG_NONE,
+            1, & pointerId, pointerCoords, mXPrecision, mYPrecision, downTime);
+}
+
+int32_t TrackballInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    if (scanCode >= BTN_MOUSE && scanCode < BTN_JOYSTICK) {
+        return getEventHub()->getScanCodeState(getDeviceId(), scanCode);
+    } else {
+        return AKEY_STATE_UNKNOWN;
+    }
+}
+
+
+// --- TouchInputMapper ---
+
+TouchInputMapper::TouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        InputMapper(device), mAssociatedDisplayId(associatedDisplayId) {
+    mLocked.surfaceOrientation = -1;
+    mLocked.surfaceWidth = -1;
+    mLocked.surfaceHeight = -1;
+
+    initializeLocked();
+}
+
+TouchInputMapper::~TouchInputMapper() {
+}
+
+uint32_t TouchInputMapper::getSources() {
+    return mAssociatedDisplayId >= 0 ? AINPUT_SOURCE_TOUCHSCREEN : AINPUT_SOURCE_TOUCHPAD;
+}
+
+void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
+    InputMapper::populateDeviceInfo(info);
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Ensure surface information is up to date so that orientation changes are
+        // noticed immediately.
+        configureSurfaceLocked();
+
+        info->addMotionRange(AINPUT_MOTION_RANGE_X, mLocked.orientedRanges.x);
+        info->addMotionRange(AINPUT_MOTION_RANGE_Y, mLocked.orientedRanges.y);
+
+        if (mLocked.orientedRanges.havePressure) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_PRESSURE,
+                    mLocked.orientedRanges.pressure);
+        }
+
+        if (mLocked.orientedRanges.haveSize) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_SIZE,
+                    mLocked.orientedRanges.size);
+        }
+
+        if (mLocked.orientedRanges.haveTouchArea) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MAJOR,
+                    mLocked.orientedRanges.touchMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOUCH_MINOR,
+                    mLocked.orientedRanges.touchMinor);
+        }
+
+        if (mLocked.orientedRanges.haveToolArea) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MAJOR,
+                    mLocked.orientedRanges.toolMajor);
+            info->addMotionRange(AINPUT_MOTION_RANGE_TOOL_MINOR,
+                    mLocked.orientedRanges.toolMinor);
+        }
+
+        if (mLocked.orientedRanges.haveOrientation) {
+            info->addMotionRange(AINPUT_MOTION_RANGE_ORIENTATION,
+                    mLocked.orientedRanges.orientation);
+        }
+    } // release lock
+}
+
+void TouchInputMapper::initializeLocked() {
+    mCurrentTouch.clear();
+    mLastTouch.clear();
+    mDownTime = 0;
+
+    for (uint32_t i = 0; i < MAX_POINTERS; i++) {
+        mAveragingTouchFilter.historyStart[i] = 0;
+        mAveragingTouchFilter.historyEnd[i] = 0;
+    }
+
+    mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+    mLocked.currentVirtualKey.down = false;
+
+    mLocked.orientedRanges.havePressure = false;
+    mLocked.orientedRanges.haveSize = false;
+    mLocked.orientedRanges.haveTouchArea = false;
+    mLocked.orientedRanges.haveToolArea = false;
+    mLocked.orientedRanges.haveOrientation = false;
+}
+
+void TouchInputMapper::configure() {
+    InputMapper::configure();
+
+    // Configure basic parameters.
+    configureParameters();
+    logParameters();
+
+    // Configure absolute axis information.
+    configureRawAxes();
+    logRawAxes();
+
+    // Prepare input device calibration.
+    parseCalibration();
+    resolveCalibration();
+    logCalibration();
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+         // Configure surface dimensions and orientation.
+        configureSurfaceLocked();
+    } // release lock
+}
+
+void TouchInputMapper::configureParameters() {
+    mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
+    mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
+    mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
+}
+
+void TouchInputMapper::logParameters() {
+    if (mParameters.useBadTouchFilter) {
+        LOGI(INDENT "Bad touch filter enabled.");
+    }
+    if (mParameters.useAveragingTouchFilter) {
+        LOGI(INDENT "Averaging touch filter enabled.");
+    }
+    if (mParameters.useJumpyTouchFilter) {
+        LOGI(INDENT "Jumpy touch filter enabled.");
+    }
+}
+
+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 logAxisInfo(RawAbsoluteAxisInfo axis, const char* name) {
+    if (axis.valid) {
+        LOGI(INDENT "Raw %s axis: min=%d, max=%d, flat=%d, fuzz=%d",
+                name, axis.minValue, axis.maxValue, axis.flat, axis.fuzz);
+    } else {
+        LOGI(INDENT "Raw %s axis: unknown range", name);
+    }
+}
+
+void TouchInputMapper::logRawAxes() {
+    logAxisInfo(mRawAxes.x, "x");
+    logAxisInfo(mRawAxes.y, "y");
+    logAxisInfo(mRawAxes.pressure, "pressure");
+    logAxisInfo(mRawAxes.touchMajor, "touchMajor");
+    logAxisInfo(mRawAxes.touchMinor, "touchMinor");
+    logAxisInfo(mRawAxes.toolMajor, "toolMajor");
+    logAxisInfo(mRawAxes.toolMinor, "toolMinor");
+    logAxisInfo(mRawAxes.orientation, "orientation");
+}
+
+bool TouchInputMapper::configureSurfaceLocked() {
+    // Update orientation and dimensions if needed.
+    int32_t orientation;
+    int32_t width, height;
+    if (mAssociatedDisplayId >= 0) {
+        // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+        if (! getPolicy()->getDisplayInfo(mAssociatedDisplayId, & width, & height, & orientation)) {
+            return false;
+        }
+    } else {
+        orientation = InputReaderPolicyInterface::ROTATION_0;
+        width = mRawAxes.x.getRange();
+        height = mRawAxes.y.getRange();
+    }
+
+    bool orientationChanged = mLocked.surfaceOrientation != orientation;
+    if (orientationChanged) {
+        mLocked.surfaceOrientation = orientation;
+    }
+
+    bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
+    if (sizeChanged) {
+        LOGI("Device reconfigured (display size changed): id=0x%x, name=%s",
+                getDeviceId(), getDeviceName().string());
+        LOGI(INDENT "Width: %dpx", width);
+        LOGI(INDENT "Height: %dpx", 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.touchAreaCalibration != Calibration::TOUCH_AREA_CALIBRATION_NONE) {
+            mLocked.orientedRanges.haveTouchArea = true;
+            mLocked.orientedRanges.touchMajor.min = 0;
+            mLocked.orientedRanges.touchMajor.max = diagonalSize;
+            mLocked.orientedRanges.touchMajor.flat = 0;
+            mLocked.orientedRanges.touchMajor.fuzz = 0;
+            mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
+        }
+
+        // ToolMajor and ToolMinor factors.
+        if (mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+            mLocked.toolAreaLinearScale = 0;
+            mLocked.toolAreaLinearBias = 0;
+            if (mCalibration.toolAreaCalibration == Calibration::TOOL_AREA_CALIBRATION_LINEAR) {
+                if (mCalibration.haveToolAreaLinearScale) {
+                    mLocked.toolAreaLinearScale = mCalibration.toolAreaLinearScale;
+                } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.toolAreaLinearScale = float(min(width, height))
+                            / mRawAxes.toolMajor.maxValue;
+                }
+
+                if (mCalibration.haveToolAreaLinearBias) {
+                    mLocked.toolAreaLinearBias = mCalibration.toolAreaLinearBias;
+                }
+            }
+
+            mLocked.orientedRanges.haveToolArea = true;
+            mLocked.orientedRanges.toolMajor.min = 0;
+            mLocked.orientedRanges.toolMajor.max = diagonalSize;
+            mLocked.orientedRanges.toolMajor.flat = 0;
+            mLocked.orientedRanges.toolMajor.fuzz = 0;
+            mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
+        }
+
+        // Pressure factors.
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
+            RawAbsoluteAxisInfo rawPressureAxis;
+            switch (mCalibration.pressureSource) {
+            case Calibration::PRESSURE_SOURCE_PRESSURE:
+                rawPressureAxis = mRawAxes.pressure;
+                break;
+            case Calibration::PRESSURE_SOURCE_TOUCH:
+                rawPressureAxis = mRawAxes.touchMajor;
+                break;
+            default:
+                rawPressureAxis.clear();
+            }
+
+            mLocked.pressureScale = 0;
+            if (mCalibration.pressureCalibration == Calibration::PRESSURE_CALIBRATION_PHYSICAL
+                    || mCalibration.pressureCalibration
+                            == Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
+                if (mCalibration.havePressureScale) {
+                    mLocked.pressureScale = mCalibration.pressureScale;
+                } else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
+                    mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.havePressure = true;
+            mLocked.orientedRanges.pressure.min = 0;
+            mLocked.orientedRanges.pressure.max = 1.0;
+            mLocked.orientedRanges.pressure.flat = 0;
+            mLocked.orientedRanges.pressure.fuzz = 0;
+        }
+
+        // Size factors.
+        if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
+            mLocked.sizeScale = 0;
+            if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
+                if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
+                    mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.haveSize = true;
+            mLocked.orientedRanges.size.min = 0;
+            mLocked.orientedRanges.size.max = 1.0;
+            mLocked.orientedRanges.size.flat = 0;
+            mLocked.orientedRanges.size.fuzz = 0;
+        }
+
+        // Orientation
+        if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
+            mLocked.orientationScale = 0;
+            if (mCalibration.orientationCalibration
+                    == Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
+                if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
+                    mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+                }
+            }
+
+            mLocked.orientedRanges.orientation.min = - M_PI_2;
+            mLocked.orientedRanges.orientation.max = M_PI_2;
+            mLocked.orientedRanges.orientation.flat = 0;
+            mLocked.orientedRanges.orientation.fuzz = 0;
+        }
+    }
+
+    if (orientationChanged || sizeChanged) {
+        // Compute oriented surface dimensions, precision, and scales.
+        float orientedXScale, orientedYScale;
+        switch (mLocked.surfaceOrientation) {
+        case InputReaderPolicyInterface::ROTATION_90:
+        case InputReaderPolicyInterface::ROTATION_270:
+            mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
+            mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
+            mLocked.orientedXPrecision = mLocked.yPrecision;
+            mLocked.orientedYPrecision = mLocked.xPrecision;
+            orientedXScale = mLocked.yScale;
+            orientedYScale = mLocked.xScale;
+            break;
+        default:
+            mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
+            mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
+            mLocked.orientedXPrecision = mLocked.xPrecision;
+            mLocked.orientedYPrecision = mLocked.yPrecision;
+            orientedXScale = mLocked.xScale;
+            orientedYScale = mLocked.yScale;
+            break;
+        }
+
+        // Configure position ranges.
+        mLocked.orientedRanges.x.min = 0;
+        mLocked.orientedRanges.x.max = mLocked.orientedSurfaceWidth;
+        mLocked.orientedRanges.x.flat = 0;
+        mLocked.orientedRanges.x.fuzz = orientedXScale;
+
+        mLocked.orientedRanges.y.min = 0;
+        mLocked.orientedRanges.y.max = mLocked.orientedSurfaceHeight;
+        mLocked.orientedRanges.y.flat = 0;
+        mLocked.orientedRanges.y.fuzz = orientedYScale;
+    }
+
+    if (sizeChanged) {
+        logMotionRangesLocked();
+    }
+
+    return true;
+}
+
+static void logMotionRangeInfo(InputDeviceInfo::MotionRange* range, const char* name) {
+    if (range) {
+        LOGI(INDENT "Output %s range: min=%f, max=%f, flat=%f, fuzz=%f",
+                name, range->min, range->max, range->flat, range->fuzz);
+    } else {
+        LOGI(INDENT "Output %s range: unsupported", name);
+    }
+}
+
+void TouchInputMapper::logMotionRangesLocked() {
+    logMotionRangeInfo(& mLocked.orientedRanges.x, "x");
+    logMotionRangeInfo(& mLocked.orientedRanges.y, "y");
+    logMotionRangeInfo(mLocked.orientedRanges.havePressure
+            ? & mLocked.orientedRanges.pressure : NULL, "pressure");
+    logMotionRangeInfo(mLocked.orientedRanges.haveSize
+            ? & mLocked.orientedRanges.size : NULL, "size");
+    logMotionRangeInfo(mLocked.orientedRanges.haveTouchArea
+            ? & mLocked.orientedRanges.touchMajor : NULL, "touchMajor");
+    logMotionRangeInfo(mLocked.orientedRanges.haveTouchArea
+            ? & mLocked.orientedRanges.touchMinor : NULL, "touchMinor");
+    logMotionRangeInfo(mLocked.orientedRanges.haveToolArea
+            ? & mLocked.orientedRanges.toolMajor : NULL, "toolMajor");
+    logMotionRangeInfo(mLocked.orientedRanges.haveToolArea
+            ? & mLocked.orientedRanges.toolMinor : NULL, "toolMinor");
+    logMotionRangeInfo(mLocked.orientedRanges.haveOrientation
+            ? & mLocked.orientedRanges.orientation : NULL, "orientation");
+}
+
+void TouchInputMapper::configureVirtualKeysLocked() {
+    assert(mRawAxes.x.valid && mRawAxes.y.valid);
+
+    // Note: getVirtualKeyDefinitions is non-reentrant so we can continue holding the lock.
+    Vector<VirtualKeyDefinition> virtualKeyDefinitions;
+    getPolicy()->getVirtualKeyDefinitions(getDeviceName(), virtualKeyDefinitions);
+
+    mLocked.virtualKeys.clear();
+
+    if (virtualKeyDefinitions.size() == 0) {
+        return;
+    }
+
+    mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+
+    int32_t touchScreenLeft = mRawAxes.x.minValue;
+    int32_t touchScreenTop = mRawAxes.y.minValue;
+    int32_t touchScreenWidth = mRawAxes.x.getRange();
+    int32_t touchScreenHeight = mRawAxes.y.getRange();
+
+    for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
+        const VirtualKeyDefinition& virtualKeyDefinition =
+                virtualKeyDefinitions[i];
+
+        mLocked.virtualKeys.add();
+        VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+
+        virtualKey.scanCode = virtualKeyDefinition.scanCode;
+        int32_t keyCode;
+        uint32_t flags;
+        if (getEventHub()->scancodeToKeycode(getDeviceId(), virtualKey.scanCode,
+                & keyCode, & flags)) {
+            LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
+                    virtualKey.scanCode);
+            mLocked.virtualKeys.pop(); // drop the key
+            continue;
+        }
+
+        virtualKey.keyCode = keyCode;
+        virtualKey.flags = flags;
+
+        // convert the key definition's display coordinates into touch coordinates for a hit box
+        int32_t halfWidth = virtualKeyDefinition.width / 2;
+        int32_t halfHeight = virtualKeyDefinition.height / 2;
+
+        virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
+                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+        virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
+                * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+        virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
+                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+        virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
+                * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+
+        LOGI(INDENT "VirtualKey %d: keyCode=%d hitLeft=%d hitRight=%d hitTop=%d hitBottom=%d",
+                virtualKey.scanCode, virtualKey.keyCode,
+                virtualKey.hitLeft, virtualKey.hitRight, virtualKey.hitTop, virtualKey.hitBottom);
+    }
+}
+
+void TouchInputMapper::parseCalibration() {
+    const InputDeviceCalibration& in = getDevice()->getCalibration();
+    Calibration& out = mCalibration;
+
+    // Touch Area
+    out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_DEFAULT;
+    String8 touchAreaCalibrationString;
+    if (in.tryGetProperty(String8("touch.touchArea.calibration"), touchAreaCalibrationString)) {
+        if (touchAreaCalibrationString == "none") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+        } else if (touchAreaCalibrationString == "geometric") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC;
+        } else if (touchAreaCalibrationString == "pressure") {
+            out.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+        } else if (touchAreaCalibrationString != "default") {
+            LOGW("Invalid value for touch.touchArea.calibration: '%s'",
+                    touchAreaCalibrationString.string());
+        }
+    }
+
+    // Tool Area
+    out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_DEFAULT;
+    String8 toolAreaCalibrationString;
+    if (in.tryGetProperty(String8("tool.toolArea.calibration"), toolAreaCalibrationString)) {
+        if (toolAreaCalibrationString == "none") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+        } else if (toolAreaCalibrationString == "geometric") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC;
+        } else if (toolAreaCalibrationString == "linear") {
+            out.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+        } else if (toolAreaCalibrationString != "default") {
+            LOGW("Invalid value for tool.toolArea.calibration: '%s'",
+                    toolAreaCalibrationString.string());
+        }
+    }
+
+    out.haveToolAreaLinearScale = in.tryGetProperty(String8("touch.toolArea.linearScale"),
+            out.toolAreaLinearScale);
+    out.haveToolAreaLinearBias = in.tryGetProperty(String8("touch.toolArea.linearBias"),
+            out.toolAreaLinearBias);
+    out.haveToolAreaIsSummed = in.tryGetProperty(String8("touch.toolArea.isSummed"),
+            out.toolAreaIsSummed);
+
+    // Pressure
+    out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_DEFAULT;
+    String8 pressureCalibrationString;
+    if (in.tryGetProperty(String8("tool.pressure.calibration"), pressureCalibrationString)) {
+        if (pressureCalibrationString == "none") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+        } else if (pressureCalibrationString == "physical") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_PHYSICAL;
+        } else if (pressureCalibrationString == "amplitude") {
+            out.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+        } else if (pressureCalibrationString != "default") {
+            LOGW("Invalid value for tool.pressure.calibration: '%s'",
+                    pressureCalibrationString.string());
+        }
+    }
+
+    out.pressureSource = Calibration::PRESSURE_SOURCE_DEFAULT;
+    String8 pressureSourceString;
+    if (in.tryGetProperty(String8("touch.pressure.source"), pressureSourceString)) {
+        if (pressureSourceString == "pressure") {
+            out.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+        } else if (pressureSourceString == "touch") {
+            out.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+        } else if (pressureSourceString != "default") {
+            LOGW("Invalid value for touch.pressure.source: '%s'",
+                    pressureSourceString.string());
+        }
+    }
+
+    out.havePressureScale = in.tryGetProperty(String8("touch.pressure.scale"),
+            out.pressureScale);
+
+    // Size
+    out.sizeCalibration = Calibration::SIZE_CALIBRATION_DEFAULT;
+    String8 sizeCalibrationString;
+    if (in.tryGetProperty(String8("tool.size.calibration"), sizeCalibrationString)) {
+        if (sizeCalibrationString == "none") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+        } else if (sizeCalibrationString == "normalized") {
+            out.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+        } else if (sizeCalibrationString != "default") {
+            LOGW("Invalid value for tool.size.calibration: '%s'",
+                    sizeCalibrationString.string());
+        }
+    }
+
+    // Orientation
+    out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_DEFAULT;
+    String8 orientationCalibrationString;
+    if (in.tryGetProperty(String8("tool.orientation.calibration"), orientationCalibrationString)) {
+        if (orientationCalibrationString == "none") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+        } else if (orientationCalibrationString == "interpolated") {
+            out.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else if (orientationCalibrationString != "default") {
+            LOGW("Invalid value for tool.orientation.calibration: '%s'",
+                    orientationCalibrationString.string());
+        }
+    }
+}
+
+void TouchInputMapper::resolveCalibration() {
+    // Pressure
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        if (mRawAxes.pressure.valid) {
+            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
+        } else if (mRawAxes.touchMajor.valid) {
+            mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
+        }
+        break;
+
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        if (! mRawAxes.pressure.valid) {
+            LOGW("Calibration property touch.pressure.source is 'pressure' but "
+                    "the pressure axis is not available.");
+        }
+        break;
+
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        if (! mRawAxes.touchMajor.valid) {
+            LOGW("Calibration property touch.pressure.source is 'touch' but "
+                    "the touchMajor axis is not available.");
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureSource != Calibration::PRESSURE_SOURCE_DEFAULT) {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_AMPLITUDE;
+        } else {
+            mCalibration.pressureCalibration = Calibration::PRESSURE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Tool Area
+    switch (mCalibration.toolAreaCalibration) {
+    case Calibration::TOOL_AREA_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_LINEAR;
+        } else {
+            mCalibration.toolAreaCalibration = Calibration::TOOL_AREA_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Touch Area
+    switch (mCalibration.touchAreaCalibration) {
+    case Calibration::TOUCH_AREA_CALIBRATION_DEFAULT:
+        if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE
+                && mCalibration.toolAreaCalibration != Calibration::TOOL_AREA_CALIBRATION_NONE) {
+            mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_PRESSURE;
+        } else {
+            mCalibration.touchAreaCalibration = Calibration::TOUCH_AREA_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_DEFAULT:
+        if (mRawAxes.toolMajor.valid) {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
+        } else {
+            mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
+        if (mRawAxes.orientation.valid) {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
+        } else {
+            mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+void TouchInputMapper::logCalibration() {
+    LOGI(INDENT "Calibration:");
+
+    // Touch Area
+    switch (mCalibration.touchAreaCalibration) {
+    case Calibration::TOUCH_AREA_CALIBRATION_NONE:
+        LOGI(INDENT INDENT "touch.touchArea.calibration: none");
+        break;
+    case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+        LOGI(INDENT INDENT "touch.touchArea.calibration: geometric");
+        break;
+    case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+        LOGI(INDENT INDENT "touch.touchArea.calibration: pressure");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Tool Area
+    switch (mCalibration.toolAreaCalibration) {
+    case Calibration::TOOL_AREA_CALIBRATION_NONE:
+        LOGI(INDENT INDENT "touch.toolArea.calibration: none");
+        break;
+    case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+        LOGI(INDENT INDENT "touch.toolArea.calibration: geometric");
+        break;
+    case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+        LOGI(INDENT INDENT "touch.toolArea.calibration: linear");
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.haveToolAreaLinearScale) {
+        LOGI(INDENT INDENT "touch.toolArea.linearScale: %f", mCalibration.toolAreaLinearScale);
+    }
+
+    if (mCalibration.haveToolAreaLinearBias) {
+        LOGI(INDENT INDENT "touch.toolArea.linearBias: %f", mCalibration.toolAreaLinearBias);
+    }
+
+    if (mCalibration.haveToolAreaIsSummed) {
+        LOGI(INDENT INDENT "touch.toolArea.isSummed: %d", mCalibration.toolAreaIsSummed);
+    }
+
+    // Pressure
+    switch (mCalibration.pressureCalibration) {
+    case Calibration::PRESSURE_CALIBRATION_NONE:
+        LOGI(INDENT INDENT "touch.pressure.calibration: none");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+        LOGI(INDENT INDENT "touch.pressure.calibration: physical");
+        break;
+    case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+        LOGI(INDENT INDENT "touch.pressure.calibration: amplitude");
+        break;
+    default:
+        assert(false);
+    }
+
+    switch (mCalibration.pressureSource) {
+    case Calibration::PRESSURE_SOURCE_PRESSURE:
+        LOGI(INDENT INDENT "touch.pressure.source: pressure");
+        break;
+    case Calibration::PRESSURE_SOURCE_TOUCH:
+        LOGI(INDENT INDENT "touch.pressure.source: touch");
+        break;
+    case Calibration::PRESSURE_SOURCE_DEFAULT:
+        break;
+    default:
+        assert(false);
+    }
+
+    if (mCalibration.havePressureScale) {
+        LOGI(INDENT INDENT "touch.pressure.scale: %f", mCalibration.pressureScale);
+    }
+
+    // Size
+    switch (mCalibration.sizeCalibration) {
+    case Calibration::SIZE_CALIBRATION_NONE:
+        LOGI(INDENT INDENT "touch.size.calibration: none");
+        break;
+    case Calibration::SIZE_CALIBRATION_NORMALIZED:
+        LOGI(INDENT INDENT "touch.size.calibration: normalized");
+        break;
+    default:
+        assert(false);
+    }
+
+    // Orientation
+    switch (mCalibration.orientationCalibration) {
+    case Calibration::ORIENTATION_CALIBRATION_NONE:
+        LOGI(INDENT INDENT "touch.orientation.calibration: none");
+        break;
+    case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+        LOGI(INDENT INDENT "touch.orientation.calibration: interpolated");
+        break;
+    default:
+        assert(false);
+    }
+}
+
+void TouchInputMapper::reset() {
+    // Synthesize touch up event if touch is currently down.
+    // This will also take care of finishing virtual key processing if needed.
+    if (mLastTouch.pointerCount != 0) {
+        nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+        mCurrentTouch.clear();
+        syncTouch(when, true);
+    }
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+        initializeLocked();
+    } // release lock
+
+    InputMapper::reset();
+}
+
+void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
+    // Apply generic policy actions.
+
+    uint32_t policyFlags = 0;
+    int32_t policyActions = getPolicy()->interceptGeneric(when, policyFlags);
+
+    if (! applyStandardPolicyActions(when, policyActions)) {
+        mLastTouch.clear();
+        return; // event dropped
+    }
+
+    // Preprocess pointer data.
+
+    if (mParameters.useBadTouchFilter) {
+        if (applyBadTouchFilter()) {
+            havePointerIds = false;
+        }
+    }
+
+    if (mParameters.useJumpyTouchFilter) {
+        if (applyJumpyTouchFilter()) {
+            havePointerIds = false;
+        }
+    }
+
+    if (! havePointerIds) {
+        calculatePointerIds();
+    }
+
+    TouchData temp;
+    TouchData* savedTouch;
+    if (mParameters.useAveragingTouchFilter) {
+        temp.copyFrom(mCurrentTouch);
+        savedTouch = & temp;
+
+        applyAveragingTouchFilter();
+    } else {
+        savedTouch = & mCurrentTouch;
+    }
+
+    // Process touches and virtual keys.
+
+    TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
+    if (touchResult == DISPATCH_TOUCH) {
+        dispatchTouches(when, policyFlags);
+    }
+
+    // Copy current touch to last touch in preparation for the next cycle.
+
+    if (touchResult == DROP_STROKE) {
+        mLastTouch.clear();
+    } else {
+        mLastTouch.copyFrom(*savedTouch);
+    }
+}
+
+TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
+        nsecs_t when, uint32_t policyFlags) {
+    int32_t keyEventAction, keyEventFlags;
+    int32_t keyCode, scanCode, downTime;
+    TouchResult touchResult;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Update surface size and orientation, including virtual key positions.
+        if (! configureSurfaceLocked()) {
+            return DROP_STROKE;
+        }
+
+        // Check for virtual key press.
+        if (mLocked.currentVirtualKey.down) {
+            if (mCurrentTouch.pointerCount == 0) {
+                // Pointer went up while virtual key was down.
+                mLocked.currentVirtualKey.down = false;
+#if DEBUG_VIRTUAL_KEYS
+                LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
+                        mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+                keyEventAction = AKEY_EVENT_ACTION_UP;
+                keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
+                touchResult = SKIP_TOUCH;
+                goto DispatchVirtualKey;
+            }
+
+            if (mCurrentTouch.pointerCount == 1) {
+                int32_t x = mCurrentTouch.pointers[0].x;
+                int32_t y = mCurrentTouch.pointers[0].y;
+                const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+                if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
+                    // Pointer is still within the space of the virtual key.
+                    return SKIP_TOUCH;
+                }
+            }
+
+            // Pointer left virtual key area or another pointer also went down.
+            // Send key cancellation and drop the stroke so subsequent motions will be
+            // considered fresh downs.  This is useful when the user swipes away from the
+            // virtual key area into the main display surface.
+            mLocked.currentVirtualKey.down = false;
+#if DEBUG_VIRTUAL_KEYS
+            LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
+                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+            keyEventAction = AKEY_EVENT_ACTION_UP;
+            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+                    | AKEY_EVENT_FLAG_CANCELED;
+            touchResult = DROP_STROKE;
+            goto DispatchVirtualKey;
+        } else {
+            if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
+                // Pointer just went down.  Handle off-screen touches, if needed.
+                int32_t x = mCurrentTouch.pointers[0].x;
+                int32_t y = mCurrentTouch.pointers[0].y;
+                if (! isPointInsideSurfaceLocked(x, y)) {
+                    // If exactly one pointer went down, check for virtual key hit.
+                    // Otherwise we will drop the entire stroke.
+                    if (mCurrentTouch.pointerCount == 1) {
+                        const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
+                        if (virtualKey) {
+                            mLocked.currentVirtualKey.down = true;
+                            mLocked.currentVirtualKey.downTime = when;
+                            mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
+                            mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
+#if DEBUG_VIRTUAL_KEYS
+                            LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+                                    mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
+#endif
+                            keyEventAction = AKEY_EVENT_ACTION_DOWN;
+                            keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
+                                    | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
+                            touchResult = SKIP_TOUCH;
+                            goto DispatchVirtualKey;
+                        }
+                    }
+                    return DROP_STROKE;
+                }
+            }
+            return DISPATCH_TOUCH;
+        }
+
+    DispatchVirtualKey:
+        // Collect remaining state needed to dispatch virtual key.
+        keyCode = mLocked.currentVirtualKey.keyCode;
+        scanCode = mLocked.currentVirtualKey.scanCode;
+        downTime = mLocked.currentVirtualKey.downTime;
+    } // release lock
+
+    // Dispatch virtual key.
+    applyPolicyAndDispatchVirtualKey(when, policyFlags, keyEventAction, keyEventFlags,
+            keyCode, scanCode, downTime);
+    return touchResult;
+}
+
+void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+        int32_t keyEventAction, int32_t keyEventFlags,
+        int32_t keyCode, int32_t scanCode, nsecs_t downTime) {
+    int32_t metaState = mContext->getGlobalMetaState();
+
+    if (keyEventAction == AKEY_EVENT_ACTION_DOWN) {
+        getPolicy()->virtualKeyDownFeedback();
+    }
+
+    int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(),
+            keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags);
+
+    if (applyStandardPolicyActions(when, policyActions)) {
+        getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+                keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+    }
+}
+
+void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
+    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
+    uint32_t lastPointerCount = mLastTouch.pointerCount;
+    if (currentPointerCount == 0 && lastPointerCount == 0) {
+        return; // nothing to do!
+    }
+
+    BitSet32 currentIdBits = mCurrentTouch.idBits;
+    BitSet32 lastIdBits = mLastTouch.idBits;
+
+    if (currentIdBits == lastIdBits) {
+        // No pointer id changes so this is a move event.
+        // The dispatcher takes care of batching moves so we don't have to deal with that here.
+        int32_t motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+        dispatchTouch(when, policyFlags, & mCurrentTouch,
+                currentIdBits, -1, currentPointerCount, motionEventAction);
+    } else {
+        // There may be pointers going up and pointers going down at the same time when pointer
+        // ids are reported by the device driver.
+        BitSet32 upIdBits(lastIdBits.value & ~ currentIdBits.value);
+        BitSet32 downIdBits(currentIdBits.value & ~ lastIdBits.value);
+        BitSet32 activeIdBits(lastIdBits.value);
+        uint32_t pointerCount = lastPointerCount;
+
+        while (! upIdBits.isEmpty()) {
+            uint32_t upId = upIdBits.firstMarkedBit();
+            upIdBits.clearBit(upId);
+            BitSet32 oldActiveIdBits = activeIdBits;
+            activeIdBits.clearBit(upId);
+
+            int32_t motionEventAction;
+            if (activeIdBits.isEmpty()) {
+                motionEventAction = AMOTION_EVENT_ACTION_UP;
+            } else {
+                motionEventAction = AMOTION_EVENT_ACTION_POINTER_UP;
+            }
+
+            dispatchTouch(when, policyFlags, & mLastTouch,
+                    oldActiveIdBits, upId, pointerCount, motionEventAction);
+            pointerCount -= 1;
+        }
+
+        while (! downIdBits.isEmpty()) {
+            uint32_t downId = downIdBits.firstMarkedBit();
+            downIdBits.clearBit(downId);
+            BitSet32 oldActiveIdBits = activeIdBits;
+            activeIdBits.markBit(downId);
+
+            int32_t motionEventAction;
+            if (oldActiveIdBits.isEmpty()) {
+                motionEventAction = AMOTION_EVENT_ACTION_DOWN;
+                mDownTime = when;
+            } else {
+                motionEventAction = AMOTION_EVENT_ACTION_POINTER_DOWN;
+            }
+
+            pointerCount += 1;
+            dispatchTouch(when, policyFlags, & mCurrentTouch,
+                    activeIdBits, downId, pointerCount, motionEventAction);
+        }
+    }
+}
+
+void TouchInputMapper::dispatchTouch(nsecs_t when, uint32_t policyFlags,
+        TouchData* touch, BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
+        int32_t motionEventAction) {
+    int32_t pointerIds[MAX_POINTERS];
+    PointerCoords pointerCoords[MAX_POINTERS];
+    int32_t motionEventEdgeFlags = 0;
+    float xPrecision, yPrecision;
+
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        // Walk through the the active pointers and map touch screen coordinates (TouchData) into
+        // display coordinates (PointerCoords) and adjust for display orientation.
+        for (uint32_t outIndex = 0; ! idBits.isEmpty(); outIndex++) {
+            uint32_t id = idBits.firstMarkedBit();
+            idBits.clearBit(id);
+            uint32_t inIndex = touch->idToIndex[id];
+
+            const PointerData& in = touch->pointers[inIndex];
+
+            // X and Y
+            float x = float(in.x - mLocked.xOrigin) * mLocked.xScale;
+            float y = float(in.y - mLocked.yOrigin) * mLocked.yScale;
+
+            // ToolMajor and ToolMinor
+            float toolMajor, toolMinor;
+            switch (mCalibration.toolAreaCalibration) {
+            case Calibration::TOOL_AREA_CALIBRATION_GEOMETRIC:
+                toolMajor = in.toolMajor * mLocked.geometricScale;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor * mLocked.geometricScale;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            case Calibration::TOOL_AREA_CALIBRATION_LINEAR:
+                toolMajor = in.toolMajor != 0
+                        ? in.toolMajor * mLocked.toolAreaLinearScale + mLocked.toolAreaLinearBias
+                        : 0;
+                if (mRawAxes.toolMinor.valid) {
+                    toolMinor = in.toolMinor != 0
+                            ? in.toolMinor * mLocked.toolAreaLinearScale
+                                    + mLocked.toolAreaLinearBias
+                            : 0;
+                } else {
+                    toolMinor = toolMajor;
+                }
+                break;
+            default:
+                toolMajor = 0;
+                toolMinor = 0;
+                break;
+            }
+
+            if (mCalibration.haveToolAreaIsSummed && mCalibration.toolAreaIsSummed) {
+                toolMajor /= pointerCount;
+                toolMinor /= pointerCount;
+            }
+
+            // Pressure
+            float rawPressure;
+            switch (mCalibration.pressureSource) {
+            case Calibration::PRESSURE_SOURCE_PRESSURE:
+                rawPressure = in.pressure;
+                break;
+            case Calibration::PRESSURE_SOURCE_TOUCH:
+                rawPressure = in.touchMajor;
+                break;
+            default:
+                rawPressure = 0;
+            }
+
+            float pressure;
+            switch (mCalibration.pressureCalibration) {
+            case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
+            case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
+                pressure = rawPressure * mLocked.pressureScale;
+                break;
+            default:
+                pressure = 1;
+                break;
+            }
+
+            // TouchMajor and TouchMinor
+            float touchMajor, touchMinor;
+            switch (mCalibration.touchAreaCalibration) {
+            case Calibration::TOUCH_AREA_CALIBRATION_GEOMETRIC:
+                touchMajor = in.touchMajor * mLocked.geometricScale;
+                if (mRawAxes.touchMinor.valid) {
+                    touchMinor = in.touchMinor * mLocked.geometricScale;
+                } else {
+                    touchMinor = touchMajor;
+                }
+                break;
+            case Calibration::TOUCH_AREA_CALIBRATION_PRESSURE:
+                touchMajor = toolMajor * pressure;
+                touchMinor = toolMinor * pressure;
+                break;
+            default:
+                touchMajor = 0;
+                touchMinor = 0;
+                break;
+            }
+
+            if (touchMajor > toolMajor) {
+                touchMajor = toolMajor;
+            }
+            if (touchMinor > toolMinor) {
+                touchMinor = toolMinor;
+            }
+
+            // Size
+            float size;
+            switch (mCalibration.sizeCalibration) {
+            case Calibration::SIZE_CALIBRATION_NORMALIZED: {
+                float rawSize = mRawAxes.toolMinor.valid
+                        ? avg(in.toolMajor, in.toolMinor)
+                        : in.toolMajor;
+                size = rawSize * mLocked.sizeScale;
+                break;
+            }
+            default:
+                size = 0;
+                break;
+            }
+
+            // Orientation
+            float orientation;
+            switch (mCalibration.orientationCalibration) {
+            case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
+                orientation = in.orientation * mLocked.orientationScale;
+                break;
+            default:
+                orientation = 0;
+            }
+
+            // Adjust coords for orientation.
+            switch (mLocked.surfaceOrientation) {
+            case InputReaderPolicyInterface::ROTATION_90: {
+                float xTemp = x;
+                x = y;
+                y = mLocked.surfaceWidth - xTemp;
+                orientation -= M_PI_2;
+                if (orientation < - M_PI_2) {
+                    orientation += M_PI;
+                }
+                break;
+            }
+            case InputReaderPolicyInterface::ROTATION_180: {
+                x = mLocked.surfaceWidth - x;
+                y = mLocked.surfaceHeight - y;
+                orientation = - orientation;
+                break;
+            }
+            case InputReaderPolicyInterface::ROTATION_270: {
+                float xTemp = x;
+                x = mLocked.surfaceHeight - y;
+                y = xTemp;
+                orientation += M_PI_2;
+                if (orientation > M_PI_2) {
+                    orientation -= M_PI;
+                }
+                break;
+            }
+            }
+
+            // Write output coords.
+            PointerCoords& out = pointerCoords[outIndex];
+            out.x = x;
+            out.y = y;
+            out.pressure = pressure;
+            out.size = size;
+            out.touchMajor = touchMajor;
+            out.touchMinor = touchMinor;
+            out.toolMajor = toolMajor;
+            out.toolMinor = toolMinor;
+            out.orientation = orientation;
+
+            pointerIds[outIndex] = int32_t(id);
+
+            if (id == changedId) {
+                motionEventAction |= outIndex << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+            }
+        }
+
+        // Check edge flags by looking only at the first pointer since the flags are
+        // global to the event.
+        if (motionEventAction == AMOTION_EVENT_ACTION_DOWN) {
+            if (pointerCoords[0].x <= 0) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_LEFT;
+            } else if (pointerCoords[0].x >= mLocked.orientedSurfaceWidth) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_RIGHT;
+            }
+            if (pointerCoords[0].y <= 0) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_TOP;
+            } else if (pointerCoords[0].y >= mLocked.orientedSurfaceHeight) {
+                motionEventEdgeFlags |= AMOTION_EVENT_EDGE_FLAG_BOTTOM;
+            }
+        }
+
+        xPrecision = mLocked.orientedXPrecision;
+        yPrecision = mLocked.orientedYPrecision;
+    } // release lock
+
+    getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_TOUCHSCREEN, policyFlags,
+            motionEventAction, 0, getContext()->getGlobalMetaState(), motionEventEdgeFlags,
+            pointerCount, pointerIds, pointerCoords,
+            xPrecision, yPrecision, mDownTime);
+}
+
+bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
+    if (mRawAxes.x.valid && mRawAxes.y.valid) {
+        return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
+                && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
+    }
+    return true;
+}
+
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+        int32_t x, int32_t y) {
+    size_t numVirtualKeys = mLocked.virtualKeys.size();
+    for (size_t i = 0; i < numVirtualKeys; i++) {
+        const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+
+#if DEBUG_VIRTUAL_KEYS
+        LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
+                "left=%d, top=%d, right=%d, bottom=%d",
+                x, y,
+                virtualKey.keyCode, virtualKey.scanCode,
+                virtualKey.hitLeft, virtualKey.hitTop,
+                virtualKey.hitRight, virtualKey.hitBottom);
+#endif
+
+        if (virtualKey.isHit(x, y)) {
+            return & virtualKey;
+        }
+    }
+
+    return NULL;
+}
+
+void TouchInputMapper::calculatePointerIds() {
+    uint32_t currentPointerCount = mCurrentTouch.pointerCount;
+    uint32_t lastPointerCount = mLastTouch.pointerCount;
+
+    if (currentPointerCount == 0) {
+        // No pointers to assign.
+        mCurrentTouch.idBits.clear();
+    } else if (lastPointerCount == 0) {
+        // All pointers are new.
+        mCurrentTouch.idBits.clear();
+        for (uint32_t i = 0; i < currentPointerCount; i++) {
+            mCurrentTouch.pointers[i].id = i;
+            mCurrentTouch.idToIndex[i] = i;
+            mCurrentTouch.idBits.markBit(i);
+        }
+    } else if (currentPointerCount == 1 && lastPointerCount == 1) {
+        // Only one pointer and no change in count so it must have the same id as before.
+        uint32_t id = mLastTouch.pointers[0].id;
+        mCurrentTouch.pointers[0].id = id;
+        mCurrentTouch.idToIndex[id] = 0;
+        mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
+    } else {
+        // General case.
+        // We build a heap of squared euclidean distances between current and last pointers
+        // associated with the current and last pointer indices.  Then, we find the best
+        // match (by distance) for each current pointer.
+        PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
+
+        uint32_t heapSize = 0;
+        for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
+                currentPointerIndex++) {
+            for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
+                    lastPointerIndex++) {
+                int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
+                        - mLastTouch.pointers[lastPointerIndex].x;
+                int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
+                        - mLastTouch.pointers[lastPointerIndex].y;
+
+                uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
+
+                // Insert new element into the heap (sift up).
+                heap[heapSize].currentPointerIndex = currentPointerIndex;
+                heap[heapSize].lastPointerIndex = lastPointerIndex;
+                heap[heapSize].distance = distance;
+                heapSize += 1;
+            }
+        }
+
+        // Heapify
+        for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
+            startIndex -= 1;
+            for (uint32_t parentIndex = startIndex; ;) {
+                uint32_t childIndex = parentIndex * 2 + 1;
+                if (childIndex >= heapSize) {
+                    break;
+                }
+
+                if (childIndex + 1 < heapSize
+                        && heap[childIndex + 1].distance < heap[childIndex].distance) {
+                    childIndex += 1;
+                }
+
+                if (heap[parentIndex].distance <= heap[childIndex].distance) {
+                    break;
+                }
+
+                swap(heap[parentIndex], heap[childIndex]);
+                parentIndex = childIndex;
+            }
+        }
+
+#if DEBUG_POINTER_ASSIGNMENT
+        LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
+        for (size_t i = 0; i < heapSize; i++) {
+            LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
+                    i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+                    heap[i].distance);
+        }
+#endif
+
+        // Pull matches out by increasing order of distance.
+        // To avoid reassigning pointers that have already been matched, the loop keeps track
+        // of which last and current pointers have been matched using the matchedXXXBits variables.
+        // It also tracks the used pointer id bits.
+        BitSet32 matchedLastBits(0);
+        BitSet32 matchedCurrentBits(0);
+        BitSet32 usedIdBits(0);
+        bool first = true;
+        for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
+            for (;;) {
+                if (first) {
+                    // The first time through the loop, we just consume the root element of
+                    // the heap (the one with smallest distance).
+                    first = false;
+                } else {
+                    // Previous iterations consumed the root element of the heap.
+                    // Pop root element off of the heap (sift down).
+                    heapSize -= 1;
+                    assert(heapSize > 0);
+
+                    // Sift down.
+                    heap[0] = heap[heapSize];
+                    for (uint32_t parentIndex = 0; ;) {
+                        uint32_t childIndex = parentIndex * 2 + 1;
+                        if (childIndex >= heapSize) {
+                            break;
+                        }
+
+                        if (childIndex + 1 < heapSize
+                                && heap[childIndex + 1].distance < heap[childIndex].distance) {
+                            childIndex += 1;
+                        }
+
+                        if (heap[parentIndex].distance <= heap[childIndex].distance) {
+                            break;
+                        }
+
+                        swap(heap[parentIndex], heap[childIndex]);
+                        parentIndex = childIndex;
+                    }
+
+#if DEBUG_POINTER_ASSIGNMENT
+                    LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
+                    for (size_t i = 0; i < heapSize; i++) {
+                        LOGD("  heap[%d]: cur=%d, last=%d, distance=%lld",
+                                i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+                                heap[i].distance);
+                    }
+#endif
+                }
+
+                uint32_t currentPointerIndex = heap[0].currentPointerIndex;
+                if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
+
+                uint32_t lastPointerIndex = heap[0].lastPointerIndex;
+                if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
+
+                matchedCurrentBits.markBit(currentPointerIndex);
+                matchedLastBits.markBit(lastPointerIndex);
+
+                uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
+                mCurrentTouch.pointers[currentPointerIndex].id = id;
+                mCurrentTouch.idToIndex[id] = currentPointerIndex;
+                usedIdBits.markBit(id);
+
+#if DEBUG_POINTER_ASSIGNMENT
+                LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
+                        lastPointerIndex, currentPointerIndex, id, heap[0].distance);
+#endif
+                break;
+            }
+        }
+
+        // Assign fresh ids to new pointers.
+        if (currentPointerCount > lastPointerCount) {
+            for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
+                uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
+                uint32_t id = usedIdBits.firstUnmarkedBit();
+
+                mCurrentTouch.pointers[currentPointerIndex].id = id;
+                mCurrentTouch.idToIndex[id] = currentPointerIndex;
+                usedIdBits.markBit(id);
+
+#if DEBUG_POINTER_ASSIGNMENT
+                LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
+                        currentPointerIndex, id);
+#endif
+
+                if (--i == 0) break; // done
+                matchedCurrentBits.markBit(currentPointerIndex);
+            }
+        }
+
+        // Fix id bits.
+        mCurrentTouch.idBits = usedIdBits;
+    }
+}
+
+/* Special hack for devices that have bad screen data: if one of the
+ * points has moved more than a screen height from the last position,
+ * then drop it. */
+bool TouchInputMapper::applyBadTouchFilter() {
+    // This hack requires valid axis parameters.
+    if (! mRawAxes.y.valid) {
+        return false;
+    }
+
+    uint32_t pointerCount = mCurrentTouch.pointerCount;
+
+    // Nothing to do if there are no points.
+    if (pointerCount == 0) {
+        return false;
+    }
+
+    // Don't do anything if a finger is going down or up.  We run
+    // here before assigning pointer IDs, so there isn't a good
+    // way to do per-finger matching.
+    if (pointerCount != mLastTouch.pointerCount) {
+        return false;
+    }
+
+    // We consider a single movement across more than a 7/16 of
+    // the long size of the screen to be bad.  This was a magic value
+    // determined by looking at the maximum distance it is feasible
+    // to actually move in one sample.
+    int32_t maxDeltaY = mRawAxes.y.getRange() * 7 / 16;
+
+    // XXX The original code in InputDevice.java included commented out
+    //     code for testing the X axis.  Note that when we drop a point
+    //     we don't actually restore the old X either.  Strange.
+    //     The old code also tries to track when bad points were previously
+    //     detected but it turns out that due to the placement of a "break"
+    //     at the end of the loop, we never set mDroppedBadPoint to true
+    //     so it is effectively dead code.
+    // Need to figure out if the old code is busted or just overcomplicated
+    // but working as intended.
+
+    // Look through all new points and see if any are farther than
+    // acceptable from all previous points.
+    for (uint32_t i = pointerCount; i-- > 0; ) {
+        int32_t y = mCurrentTouch.pointers[i].y;
+        int32_t closestY = INT_MAX;
+        int32_t closestDeltaY = 0;
+
+#if DEBUG_HACKS
+        LOGD("BadTouchFilter: Looking at next point #%d: y=%d", i, y);
+#endif
+
+        for (uint32_t j = pointerCount; j-- > 0; ) {
+            int32_t lastY = mLastTouch.pointers[j].y;
+            int32_t deltaY = abs(y - lastY);
+
+#if DEBUG_HACKS
+            LOGD("BadTouchFilter: Comparing with last point #%d: y=%d deltaY=%d",
+                    j, lastY, deltaY);
+#endif
+
+            if (deltaY < maxDeltaY) {
+                goto SkipSufficientlyClosePoint;
+            }
+            if (deltaY < closestDeltaY) {
+                closestDeltaY = deltaY;
+                closestY = lastY;
+            }
+        }
+
+        // Must not have found a close enough match.
+#if DEBUG_HACKS
+        LOGD("BadTouchFilter: Dropping bad point #%d: newY=%d oldY=%d deltaY=%d maxDeltaY=%d",
+                i, y, closestY, closestDeltaY, maxDeltaY);
+#endif
+
+        mCurrentTouch.pointers[i].y = closestY;
+        return true; // XXX original code only corrects one point
+
+    SkipSufficientlyClosePoint: ;
+    }
+
+    // No change.
+    return false;
+}
+
+/* Special hack for devices that have bad screen data: drop points where
+ * the coordinate value for one axis has jumped to the other pointer's location.
+ */
+bool TouchInputMapper::applyJumpyTouchFilter() {
+    // This hack requires valid axis parameters.
+    if (! mRawAxes.y.valid) {
+        return false;
+    }
+
+    uint32_t pointerCount = mCurrentTouch.pointerCount;
+    if (mLastTouch.pointerCount != pointerCount) {
+#if DEBUG_HACKS
+        LOGD("JumpyTouchFilter: Different pointer count %d -> %d",
+                mLastTouch.pointerCount, pointerCount);
+        for (uint32_t i = 0; i < pointerCount; i++) {
+            LOGD("  Pointer %d (%d, %d)", i,
+                    mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
+        }
+#endif
+
+        if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_TRANSITION_DROPS) {
+            if (mLastTouch.pointerCount == 1 && pointerCount == 2) {
+                // Just drop the first few events going from 1 to 2 pointers.
+                // They're bad often enough that they're not worth considering.
+                mCurrentTouch.pointerCount = 1;
+                mJumpyTouchFilter.jumpyPointsDropped += 1;
+
+#if DEBUG_HACKS
+                LOGD("JumpyTouchFilter: Pointer 2 dropped");
+#endif
+                return true;
+            } else if (mLastTouch.pointerCount == 2 && pointerCount == 1) {
+                // The event when we go from 2 -> 1 tends to be messed up too
+                mCurrentTouch.pointerCount = 2;
+                mCurrentTouch.pointers[0] = mLastTouch.pointers[0];
+                mCurrentTouch.pointers[1] = mLastTouch.pointers[1];
+                mJumpyTouchFilter.jumpyPointsDropped += 1;
+
+#if DEBUG_HACKS
+                for (int32_t i = 0; i < 2; i++) {
+                    LOGD("JumpyTouchFilter: Pointer %d replaced (%d, %d)", i,
+                            mCurrentTouch.pointers[i].x, mCurrentTouch.pointers[i].y);
+                }
+#endif
+                return true;
+            }
+        }
+        // Reset jumpy points dropped on other transitions or if limit exceeded.
+        mJumpyTouchFilter.jumpyPointsDropped = 0;
+
+#if DEBUG_HACKS
+        LOGD("JumpyTouchFilter: Transition - drop limit reset");
+#endif
+        return false;
+    }
+
+    // We have the same number of pointers as last time.
+    // A 'jumpy' point is one where the coordinate value for one axis
+    // has jumped to the other pointer's location. No need to do anything
+    // else if we only have one pointer.
+    if (pointerCount < 2) {
+        return false;
+    }
+
+    if (mJumpyTouchFilter.jumpyPointsDropped < JUMPY_DROP_LIMIT) {
+        int jumpyEpsilon = mRawAxes.y.getRange() / JUMPY_EPSILON_DIVISOR;
+
+        // We only replace the single worst jumpy point as characterized by pointer distance
+        // in a single axis.
+        int32_t badPointerIndex = -1;
+        int32_t badPointerReplacementIndex = -1;
+        int32_t badPointerDistance = INT_MIN; // distance to be corrected
+
+        for (uint32_t i = pointerCount; i-- > 0; ) {
+            int32_t x = mCurrentTouch.pointers[i].x;
+            int32_t y = mCurrentTouch.pointers[i].y;
+
+#if DEBUG_HACKS
+            LOGD("JumpyTouchFilter: Point %d (%d, %d)", i, x, y);
+#endif
+
+            // Check if a touch point is too close to another's coordinates
+            bool dropX = false, dropY = false;
+            for (uint32_t j = 0; j < pointerCount; j++) {
+                if (i == j) {
+                    continue;
+                }
+
+                if (abs(x - mCurrentTouch.pointers[j].x) <= jumpyEpsilon) {
+                    dropX = true;
+                    break;
+                }
+
+                if (abs(y - mCurrentTouch.pointers[j].y) <= jumpyEpsilon) {
+                    dropY = true;
+                    break;
+                }
+            }
+            if (! dropX && ! dropY) {
+                continue; // not jumpy
+            }
+
+            // Find a replacement candidate by comparing with older points on the
+            // complementary (non-jumpy) axis.
+            int32_t distance = INT_MIN; // distance to be corrected
+            int32_t replacementIndex = -1;
+
+            if (dropX) {
+                // X looks too close.  Find an older replacement point with a close Y.
+                int32_t smallestDeltaY = INT_MAX;
+                for (uint32_t j = 0; j < pointerCount; j++) {
+                    int32_t deltaY = abs(y - mLastTouch.pointers[j].y);
+                    if (deltaY < smallestDeltaY) {
+                        smallestDeltaY = deltaY;
+                        replacementIndex = j;
+                    }
+                }
+                distance = abs(x - mLastTouch.pointers[replacementIndex].x);
+            } else {
+                // Y looks too close.  Find an older replacement point with a close X.
+                int32_t smallestDeltaX = INT_MAX;
+                for (uint32_t j = 0; j < pointerCount; j++) {
+                    int32_t deltaX = abs(x - mLastTouch.pointers[j].x);
+                    if (deltaX < smallestDeltaX) {
+                        smallestDeltaX = deltaX;
+                        replacementIndex = j;
+                    }
+                }
+                distance = abs(y - mLastTouch.pointers[replacementIndex].y);
+            }
+
+            // If replacing this pointer would correct a worse error than the previous ones
+            // considered, then use this replacement instead.
+            if (distance > badPointerDistance) {
+                badPointerIndex = i;
+                badPointerReplacementIndex = replacementIndex;
+                badPointerDistance = distance;
+            }
+        }
+
+        // Correct the jumpy pointer if one was found.
+        if (badPointerIndex >= 0) {
+#if DEBUG_HACKS
+            LOGD("JumpyTouchFilter: Replacing bad pointer %d with (%d, %d)",
+                    badPointerIndex,
+                    mLastTouch.pointers[badPointerReplacementIndex].x,
+                    mLastTouch.pointers[badPointerReplacementIndex].y);
+#endif
+
+            mCurrentTouch.pointers[badPointerIndex].x =
+                    mLastTouch.pointers[badPointerReplacementIndex].x;
+            mCurrentTouch.pointers[badPointerIndex].y =
+                    mLastTouch.pointers[badPointerReplacementIndex].y;
+            mJumpyTouchFilter.jumpyPointsDropped += 1;
+            return true;
+        }
+    }
+
+    mJumpyTouchFilter.jumpyPointsDropped = 0;
+    return false;
+}
+
+/* Special hack for devices that have bad screen data: aggregate and
+ * compute averages of the coordinate data, to reduce the amount of
+ * jitter seen by applications. */
+void TouchInputMapper::applyAveragingTouchFilter() {
+    for (uint32_t currentIndex = 0; currentIndex < mCurrentTouch.pointerCount; currentIndex++) {
+        uint32_t id = mCurrentTouch.pointers[currentIndex].id;
+        int32_t x = mCurrentTouch.pointers[currentIndex].x;
+        int32_t y = mCurrentTouch.pointers[currentIndex].y;
+        int32_t pressure;
+        switch (mCalibration.pressureSource) {
+        case Calibration::PRESSURE_SOURCE_PRESSURE:
+            pressure = mCurrentTouch.pointers[currentIndex].pressure;
+            break;
+        case Calibration::PRESSURE_SOURCE_TOUCH:
+            pressure = mCurrentTouch.pointers[currentIndex].touchMajor;
+            break;
+        default:
+            pressure = 1;
+            break;
+        }
+
+        if (mLastTouch.idBits.hasBit(id)) {
+            // Pointer was down before and is still down now.
+            // Compute average over history trace.
+            uint32_t start = mAveragingTouchFilter.historyStart[id];
+            uint32_t end = mAveragingTouchFilter.historyEnd[id];
+
+            int64_t deltaX = x - mAveragingTouchFilter.historyData[end].pointers[id].x;
+            int64_t deltaY = y - mAveragingTouchFilter.historyData[end].pointers[id].y;
+            uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
+
+#if DEBUG_HACKS
+            LOGD("AveragingTouchFilter: Pointer id %d - Distance from last sample: %lld",
+                    id, distance);
+#endif
+
+            if (distance < AVERAGING_DISTANCE_LIMIT) {
+                // Increment end index in preparation for recording new historical data.
+                end += 1;
+                if (end > AVERAGING_HISTORY_SIZE) {
+                    end = 0;
+                }
+
+                // If the end index has looped back to the start index then we have filled
+                // the historical trace up to the desired size so we drop the historical
+                // data at the start of the trace.
+                if (end == start) {
+                    start += 1;
+                    if (start > AVERAGING_HISTORY_SIZE) {
+                        start = 0;
+                    }
+                }
+
+                // Add the raw data to the historical trace.
+                mAveragingTouchFilter.historyStart[id] = start;
+                mAveragingTouchFilter.historyEnd[id] = end;
+                mAveragingTouchFilter.historyData[end].pointers[id].x = x;
+                mAveragingTouchFilter.historyData[end].pointers[id].y = y;
+                mAveragingTouchFilter.historyData[end].pointers[id].pressure = pressure;
+
+                // Average over all historical positions in the trace by total pressure.
+                int32_t averagedX = 0;
+                int32_t averagedY = 0;
+                int32_t totalPressure = 0;
+                for (;;) {
+                    int32_t historicalX = mAveragingTouchFilter.historyData[start].pointers[id].x;
+                    int32_t historicalY = mAveragingTouchFilter.historyData[start].pointers[id].y;
+                    int32_t historicalPressure = mAveragingTouchFilter.historyData[start]
+                            .pointers[id].pressure;
+
+                    averagedX += historicalX * historicalPressure;
+                    averagedY += historicalY * historicalPressure;
+                    totalPressure += historicalPressure;
+
+                    if (start == end) {
+                        break;
+                    }
+
+                    start += 1;
+                    if (start > AVERAGING_HISTORY_SIZE) {
+                        start = 0;
+                    }
+                }
+
+                if (totalPressure != 0) {
+                    averagedX /= totalPressure;
+                    averagedY /= totalPressure;
+
+#if DEBUG_HACKS
+                    LOGD("AveragingTouchFilter: Pointer id %d - "
+                            "totalPressure=%d, averagedX=%d, averagedY=%d", id, totalPressure,
+                            averagedX, averagedY);
+#endif
+
+                    mCurrentTouch.pointers[currentIndex].x = averagedX;
+                    mCurrentTouch.pointers[currentIndex].y = averagedY;
+                }
+            } else {
+#if DEBUG_HACKS
+                LOGD("AveragingTouchFilter: Pointer id %d - Exceeded max distance", id);
+#endif
+            }
+        } else {
+#if DEBUG_HACKS
+            LOGD("AveragingTouchFilter: Pointer id %d - Pointer went up", id);
+#endif
+        }
+
+        // Reset pointer history.
+        mAveragingTouchFilter.historyStart[id] = 0;
+        mAveragingTouchFilter.historyEnd[id] = 0;
+        mAveragingTouchFilter.historyData[0].pointers[id].x = x;
+        mAveragingTouchFilter.historyData[0].pointers[id].y = y;
+        mAveragingTouchFilter.historyData[0].pointers[id].pressure = pressure;
+    }
+}
+
+int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
+            return AKEY_STATE_VIRTUAL;
+        }
+
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+            if (virtualKey.keyCode == keyCode) {
+                return AKEY_STATE_UP;
+            }
+        }
+    } // release lock
+
+    return AKEY_STATE_UNKNOWN;
+}
+
+int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
+            return AKEY_STATE_VIRTUAL;
+        }
+
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+            if (virtualKey.scanCode == scanCode) {
+                return AKEY_STATE_UP;
+            }
+        }
+    } // release lock
+
+    return AKEY_STATE_UNKNOWN;
+}
+
+bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
+        const int32_t* keyCodes, uint8_t* outFlags) {
+    { // acquire lock
+        AutoMutex _l(mLock);
+
+        size_t numVirtualKeys = mLocked.virtualKeys.size();
+        for (size_t i = 0; i < numVirtualKeys; i++) {
+            const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+
+            for (size_t i = 0; i < numCodes; i++) {
+                if (virtualKey.keyCode == keyCodes[i]) {
+                    outFlags[i] = 1;
+                }
+            }
+        }
+    } // release lock
+
+    return true;
+}
+
+
+// --- SingleTouchInputMapper ---
+
+SingleTouchInputMapper::SingleTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        TouchInputMapper(device, associatedDisplayId) {
+    initialize();
+}
+
+SingleTouchInputMapper::~SingleTouchInputMapper() {
+}
+
+void SingleTouchInputMapper::initialize() {
+    mAccumulator.clear();
+
+    mDown = false;
+    mX = 0;
+    mY = 0;
+    mPressure = 0; // default to 0 for devices that don't report pressure
+    mToolWidth = 0; // default to 0 for devices that don't report tool width
+}
+
+void SingleTouchInputMapper::reset() {
+    TouchInputMapper::reset();
+
+    initialize();
+ }
+
+void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_KEY:
+        switch (rawEvent->scanCode) {
+        case BTN_TOUCH:
+            mAccumulator.fields |= Accumulator::FIELD_BTN_TOUCH;
+            mAccumulator.btnTouch = rawEvent->value != 0;
+            // Don't sync immediately.  Wait until the next SYN_REPORT since we might
+            // not have received valid position information yet.  This logic assumes that
+            // BTN_TOUCH is always followed by SYN_REPORT as part of a complete packet.
+            break;
+        }
+        break;
+
+    case EV_ABS:
+        switch (rawEvent->scanCode) {
+        case ABS_X:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_X;
+            mAccumulator.absX = rawEvent->value;
+            break;
+        case ABS_Y:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_Y;
+            mAccumulator.absY = rawEvent->value;
+            break;
+        case ABS_PRESSURE:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_PRESSURE;
+            mAccumulator.absPressure = rawEvent->value;
+            break;
+        case ABS_TOOL_WIDTH:
+            mAccumulator.fields |= Accumulator::FIELD_ABS_TOOL_WIDTH;
+            mAccumulator.absToolWidth = rawEvent->value;
+            break;
+        }
+        break;
+
+    case EV_SYN:
+        switch (rawEvent->scanCode) {
+        case SYN_REPORT:
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+    }
+}
+
+void SingleTouchInputMapper::sync(nsecs_t when) {
+    uint32_t fields = mAccumulator.fields;
+    if (fields == 0) {
+        return; // no new state changes, so nothing to do
+    }
+
+    if (fields & Accumulator::FIELD_BTN_TOUCH) {
+        mDown = mAccumulator.btnTouch;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_X) {
+        mX = mAccumulator.absX;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_Y) {
+        mY = mAccumulator.absY;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_PRESSURE) {
+        mPressure = mAccumulator.absPressure;
+    }
+
+    if (fields & Accumulator::FIELD_ABS_TOOL_WIDTH) {
+        mToolWidth = mAccumulator.absToolWidth;
+    }
+
+    mCurrentTouch.clear();
+
+    if (mDown) {
+        mCurrentTouch.pointerCount = 1;
+        mCurrentTouch.pointers[0].id = 0;
+        mCurrentTouch.pointers[0].x = mX;
+        mCurrentTouch.pointers[0].y = mY;
+        mCurrentTouch.pointers[0].pressure = mPressure;
+        mCurrentTouch.pointers[0].touchMajor = 0;
+        mCurrentTouch.pointers[0].touchMinor = 0;
+        mCurrentTouch.pointers[0].toolMajor = mToolWidth;
+        mCurrentTouch.pointers[0].toolMinor = mToolWidth;
+        mCurrentTouch.pointers[0].orientation = 0;
+        mCurrentTouch.idToIndex[0] = 0;
+        mCurrentTouch.idBits.markBit(0);
+    }
+
+    syncTouch(when, true);
+
+    mAccumulator.clear();
+}
+
+void SingleTouchInputMapper::configureRawAxes() {
+    TouchInputMapper::configureRawAxes();
+
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
+}
+
+
+// --- MultiTouchInputMapper ---
+
+MultiTouchInputMapper::MultiTouchInputMapper(InputDevice* device, int32_t associatedDisplayId) :
+        TouchInputMapper(device, associatedDisplayId) {
+    initialize();
+}
+
+MultiTouchInputMapper::~MultiTouchInputMapper() {
+}
+
+void MultiTouchInputMapper::initialize() {
+    mAccumulator.clear();
+}
+
+void MultiTouchInputMapper::reset() {
+    TouchInputMapper::reset();
+
+    initialize();
+}
+
+void MultiTouchInputMapper::process(const RawEvent* rawEvent) {
+    switch (rawEvent->type) {
+    case EV_ABS: {
+        uint32_t pointerIndex = mAccumulator.pointerCount;
+        Accumulator::Pointer* pointer = & mAccumulator.pointers[pointerIndex];
+
+        switch (rawEvent->scanCode) {
+        case ABS_MT_POSITION_X:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_X;
+            pointer->absMTPositionX = rawEvent->value;
+            break;
+        case ABS_MT_POSITION_Y:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_POSITION_Y;
+            pointer->absMTPositionY = rawEvent->value;
+            break;
+        case ABS_MT_TOUCH_MAJOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MAJOR;
+            pointer->absMTTouchMajor = rawEvent->value;
+            break;
+        case ABS_MT_TOUCH_MINOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_TOUCH_MINOR;
+            pointer->absMTTouchMinor = rawEvent->value;
+            break;
+        case ABS_MT_WIDTH_MAJOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MAJOR;
+            pointer->absMTWidthMajor = rawEvent->value;
+            break;
+        case ABS_MT_WIDTH_MINOR:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_WIDTH_MINOR;
+            pointer->absMTWidthMinor = rawEvent->value;
+            break;
+        case ABS_MT_ORIENTATION:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_ORIENTATION;
+            pointer->absMTOrientation = rawEvent->value;
+            break;
+        case ABS_MT_TRACKING_ID:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_TRACKING_ID;
+            pointer->absMTTrackingId = rawEvent->value;
+            break;
+        case ABS_MT_PRESSURE:
+            pointer->fields |= Accumulator::FIELD_ABS_MT_PRESSURE;
+            pointer->absMTPressure = rawEvent->value;
+            break;
+        }
+        break;
+    }
+
+    case EV_SYN:
+        switch (rawEvent->scanCode) {
+        case SYN_MT_REPORT: {
+            // MultiTouch Sync: The driver has returned all data for *one* of the pointers.
+            uint32_t pointerIndex = mAccumulator.pointerCount;
+
+            if (mAccumulator.pointers[pointerIndex].fields) {
+                if (pointerIndex == MAX_POINTERS) {
+                    LOGW("MultiTouch device driver returned more than maximum of %d pointers.",
+                            MAX_POINTERS);
+                } else {
+                    pointerIndex += 1;
+                    mAccumulator.pointerCount = pointerIndex;
+                }
+            }
+
+            mAccumulator.pointers[pointerIndex].clear();
+            break;
+        }
+
+        case SYN_REPORT:
+            sync(rawEvent->when);
+            break;
+        }
+        break;
+    }
+}
+
+void MultiTouchInputMapper::sync(nsecs_t when) {
+    static const uint32_t REQUIRED_FIELDS =
+            Accumulator::FIELD_ABS_MT_POSITION_X | Accumulator::FIELD_ABS_MT_POSITION_Y;
+
+    uint32_t inCount = mAccumulator.pointerCount;
+    uint32_t outCount = 0;
+    bool havePointerIds = true;
+
+    mCurrentTouch.clear();
+
+    for (uint32_t inIndex = 0; inIndex < inCount; inIndex++) {
+        const Accumulator::Pointer& inPointer = mAccumulator.pointers[inIndex];
+        uint32_t fields = inPointer.fields;
+
+        if ((fields & REQUIRED_FIELDS) != REQUIRED_FIELDS) {
+            // Some drivers send empty MT sync packets without X / Y to indicate a pointer up.
+            // Drop this finger.
+            continue;
+        }
+
+        PointerData& outPointer = mCurrentTouch.pointers[outCount];
+        outPointer.x = inPointer.absMTPositionX;
+        outPointer.y = inPointer.absMTPositionY;
+
+        if (fields & Accumulator::FIELD_ABS_MT_PRESSURE) {
+            if (inPointer.absMTPressure <= 0) {
+                // Some devices send sync packets with X / Y but with a 0 presure to indicate
+                // a pointer up.  Drop this finger.
+                continue;
+            }
+            outPointer.pressure = inPointer.absMTPressure;
+        } else {
+            // Default pressure to 0 if absent.
+            outPointer.pressure = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MAJOR) {
+            if (inPointer.absMTTouchMajor <= 0) {
+                // Some devices send sync packets with X / Y but with a 0 touch major to indicate
+                // a pointer going up.  Drop this finger.
+                continue;
+            }
+            outPointer.touchMajor = inPointer.absMTTouchMajor;
+        } else {
+            // Default touch area to 0 if absent.
+            outPointer.touchMajor = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_TOUCH_MINOR) {
+            outPointer.touchMinor = inPointer.absMTTouchMinor;
+        } else {
+            // Assume touch area is circular.
+            outPointer.touchMinor = outPointer.touchMajor;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MAJOR) {
+            outPointer.toolMajor = inPointer.absMTWidthMajor;
+        } else {
+            // Default tool area to 0 if absent.
+            outPointer.toolMajor = 0;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_WIDTH_MINOR) {
+            outPointer.toolMinor = inPointer.absMTWidthMinor;
+        } else {
+            // Assume tool area is circular.
+            outPointer.toolMinor = outPointer.toolMajor;
+        }
+
+        if (fields & Accumulator::FIELD_ABS_MT_ORIENTATION) {
+            outPointer.orientation = inPointer.absMTOrientation;
+        } else {
+            // Default orientation to vertical if absent.
+            outPointer.orientation = 0;
+        }
+
+        // Assign pointer id using tracking id if available.
+        if (havePointerIds) {
+            if (fields & Accumulator::FIELD_ABS_MT_TRACKING_ID) {
+                uint32_t id = uint32_t(inPointer.absMTTrackingId);
+
+                if (id > MAX_POINTER_ID) {
+#if DEBUG_POINTERS
+                    LOGD("Pointers: Ignoring driver provided pointer id %d because "
+                            "it is larger than max supported id %d for optimizations",
+                            id, MAX_POINTER_ID);
+#endif
+                    havePointerIds = false;
+                }
+                else {
+                    outPointer.id = id;
+                    mCurrentTouch.idToIndex[id] = outCount;
+                    mCurrentTouch.idBits.markBit(id);
+                }
+            } else {
+                havePointerIds = false;
+            }
+        }
+
+        outCount += 1;
+    }
+
+    mCurrentTouch.pointerCount = outCount;
+
+    syncTouch(when, havePointerIds);
+
+    mAccumulator.clear();
+}
+
+void MultiTouchInputMapper::configureRawAxes() {
+    TouchInputMapper::configureRawAxes();
+
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, & mRawAxes.x);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, & mRawAxes.y);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, & mRawAxes.touchMajor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, & mRawAxes.touchMinor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, & mRawAxes.toolMajor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, & mRawAxes.toolMinor);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, & mRawAxes.orientation);
+    getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, & mRawAxes.pressure);
+}
+
+
+} // namespace android
diff --git a/libs/ui/InputTransport.cpp b/libs/ui/InputTransport.cpp
new file mode 100644
index 0000000..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/tests/Android.mk b/libs/ui/tests/Android.mk
index 6cc4a5a..62f824f 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -1,16 +1,50 @@
+# Build the unit tests.
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES:= \
-	region.cpp
+ifneq ($(TARGET_SIMULATOR),true)
 
-LOCAL_SHARED_LIBRARIES := \
+# Build the unit tests.
+test_src_files := \
+    InputChannel_test.cpp \
+    InputDispatcher_test.cpp \
+    InputPublisherAndConsumer_test.cpp
+
+shared_libraries := \
 	libcutils \
 	libutils \
-    libui
+	libEGL \
+	libbinder \
+	libpixelflinger \
+	libhardware \
+	libhardware_legacy \
+	libui \
+	libstlport
 
-LOCAL_MODULE:= test-region
+static_libraries := \
+	libgtest \
+	libgtest_main
 
-LOCAL_MODULE_TAGS := tests
+c_includes := \
+    bionic \
+    bionic/libstdc++/include \
+    external/gtest/include \
+    external/stlport/stlport
 
-include $(BUILD_EXECUTABLE)
+module_tags := eng tests
+
+$(foreach file,$(test_src_files), \
+    $(eval include $(CLEAR_VARS)) \
+    $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+    $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+    $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+    $(eval LOCAL_SRC_FILES := $(file)) \
+    $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+    $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+    $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
+include $(call all-subdir-makefiles)
+
+endif
\ No newline at end of file
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/ui/tests/InputChannel_test.cpp
new file mode 100644
index 0000000..6cec1c0
--- /dev/null
+++ b/libs/ui/tests/InputChannel_test.cpp
@@ -0,0 +1,158 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputTransport.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <cutils/ashmem.h>
+
+#include "../../utils/tests/TestHelpers.h"
+
+namespace android {
+
+class InputChannelTest : public testing::Test {
+protected:
+    virtual void SetUp() { }
+    virtual void TearDown() { }
+};
+
+
+TEST_F(InputChannelTest, ConstructorAndDestructor_TakesOwnershipOfFileDescriptors) {
+    // Our purpose here is to verify that the input channel destructor closes the
+    // file descriptors provided to it.  One easy way is to provide it with one end
+    // of a pipe and to check for EPIPE on the other end after the channel is destroyed.
+    Pipe fakeAshmem, sendPipe, receivePipe;
+
+    sp<InputChannel> inputChannel = new InputChannel(String8("channel name"),
+            fakeAshmem.sendFd, receivePipe.receiveFd, sendPipe.sendFd);
+
+    EXPECT_STREQ("channel name", inputChannel->getName().string())
+            << "channel should have provided name";
+    EXPECT_EQ(fakeAshmem.sendFd, inputChannel->getAshmemFd())
+            << "channel should have provided ashmem fd";
+    EXPECT_EQ(receivePipe.receiveFd, inputChannel->getReceivePipeFd())
+            << "channel should have provided receive pipe fd";
+    EXPECT_EQ(sendPipe.sendFd, inputChannel->getSendPipeFd())
+            << "channel should have provided send pipe fd";
+
+    inputChannel.clear(); // destroys input channel
+
+    EXPECT_EQ(-EPIPE, fakeAshmem.readSignal())
+            << "channel should have closed ashmem fd when destroyed";
+    EXPECT_EQ(-EPIPE, receivePipe.writeSignal())
+            << "channel should have closed receive pipe fd when destroyed";
+    EXPECT_EQ(-EPIPE, sendPipe.readSignal())
+            << "channel should have closed send pipe fd when destroyed";
+
+    // clean up fds of Pipe endpoints that were closed so we don't try to close them again
+    fakeAshmem.sendFd = -1;
+    receivePipe.receiveFd = -1;
+    sendPipe.sendFd = -1;
+}
+
+TEST_F(InputChannelTest, OpenInputChannelPair_ReturnsAPairOfConnectedChannels) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    // Name
+    EXPECT_STREQ("channel name (server)", serverChannel->getName().string())
+            << "server channel should have suffixed name";
+    EXPECT_STREQ("channel name (client)", clientChannel->getName().string())
+            << "client channel should have suffixed name";
+
+    // Ashmem uniqueness
+    EXPECT_NE(serverChannel->getAshmemFd(), clientChannel->getAshmemFd())
+            << "server and client channel should have different ashmem fds because it was dup'd";
+
+    // Ashmem usability
+    ssize_t serverAshmemSize = ashmem_get_size_region(serverChannel->getAshmemFd());
+    ssize_t clientAshmemSize = ashmem_get_size_region(clientChannel->getAshmemFd());
+    uint32_t* serverAshmem = static_cast<uint32_t*>(mmap(NULL, serverAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, serverChannel->getAshmemFd(), 0));
+    uint32_t* clientAshmem = static_cast<uint32_t*>(mmap(NULL, clientAshmemSize,
+            PROT_READ | PROT_WRITE, MAP_SHARED, clientChannel->getAshmemFd(), 0));
+    ASSERT_TRUE(serverAshmem != NULL)
+            << "server channel ashmem should be mappable";
+    ASSERT_TRUE(clientAshmem != NULL)
+            << "client channel ashmem should be mappable";
+    *serverAshmem = 0xf00dd00d;
+    EXPECT_EQ(0xf00dd00d, *clientAshmem)
+            << "ashmem buffer should be shared by client and server";
+    munmap(serverAshmem, serverAshmemSize);
+    munmap(clientAshmem, clientAshmemSize);
+
+    // Server->Client communication
+    EXPECT_EQ(OK, serverChannel->sendSignal('S'))
+            << "server channel should be able to send signal to client channel";
+    char signal;
+    EXPECT_EQ(OK, clientChannel->receiveSignal(& signal))
+            << "client channel should be able to receive signal from server channel";
+    EXPECT_EQ('S', signal)
+            << "client channel should receive the correct signal from server channel";
+
+    // Client->Server communication
+    EXPECT_EQ(OK, clientChannel->sendSignal('c'))
+            << "client channel should be able to send signal to server channel";
+    EXPECT_EQ(OK, serverChannel->receiveSignal(& signal))
+            << "server channel should be able to receive signal from client channel";
+    EXPECT_EQ('c', signal)
+            << "server channel should receive the correct signal from client channel";
+}
+
+TEST_F(InputChannelTest, ReceiveSignal_WhenNoSignalPresent_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    char signal;
+    EXPECT_EQ(WOULD_BLOCK, clientChannel->receiveSignal(& signal))
+            << "receiveSignal should have returned WOULD_BLOCK";
+}
+
+TEST_F(InputChannelTest, ReceiveSignal_WhenPeerClosed_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    serverChannel.clear(); // close server channel
+
+    char signal;
+    EXPECT_EQ(DEAD_OBJECT, clientChannel->receiveSignal(& signal))
+            << "receiveSignal should have returned DEAD_OBJECT";
+}
+
+TEST_F(InputChannelTest, SendSignal_WhenPeerClosed_ReturnsAnError) {
+    sp<InputChannel> serverChannel, clientChannel;
+
+    status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+            serverChannel, clientChannel);
+
+    ASSERT_EQ(OK, result)
+            << "should have successfully opened a channel pair";
+
+    serverChannel.clear(); // close server channel
+
+    EXPECT_EQ(DEAD_OBJECT, clientChannel->sendSignal('S'))
+            << "sendSignal should have returned DEAD_OBJECT";
+}
+
+
+} // namespace android
diff --git a/libs/ui/tests/InputDispatcher_test.cpp b/libs/ui/tests/InputDispatcher_test.cpp
new file mode 100644
index 0000000..1dc6e46
--- /dev/null
+++ b/libs/ui/tests/InputDispatcher_test.cpp
@@ -0,0 +1,18 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputDispatcher.h>
+#include <gtest/gtest.h>
+
+namespace android {
+
+class InputDispatcherTest : public testing::Test {
+public:
+};
+
+TEST_F(InputDispatcherTest, Dummy) {
+    // TODO
+}
+
+} // namespace android
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
new file mode 100644
index 0000000..952b974
--- /dev/null
+++ b/libs/ui/tests/InputPublisherAndConsumer_test.cpp
@@ -0,0 +1,471 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+
+#include <ui/InputTransport.h>
+#include <utils/Timers.h>
+#include <utils/StopWatch.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/mman.h>
+#include <cutils/ashmem.h>
+
+#include "../../utils/tests/TestHelpers.h"
+
+namespace android {
+
+class InputPublisherAndConsumerTest : public testing::Test {
+protected:
+    sp<InputChannel> serverChannel, clientChannel;
+    InputPublisher* mPublisher;
+    InputConsumer* mConsumer;
+    PreallocatedInputEventFactory mEventFactory;
+
+    virtual void SetUp() {
+        status_t result = InputChannel::openInputChannelPair(String8("channel name"),
+                serverChannel, clientChannel);
+
+        mPublisher = new InputPublisher(serverChannel);
+        mConsumer = new InputConsumer(clientChannel);
+    }
+
+    virtual void TearDown() {
+        if (mPublisher) {
+            delete mPublisher;
+            mPublisher = NULL;
+        }
+
+        if (mConsumer) {
+            delete mConsumer;
+            mConsumer = NULL;
+        }
+
+        serverChannel.clear();
+        clientChannel.clear();
+    }
+
+    void Initialize();
+    void PublishAndConsumeKeyEvent();
+    void PublishAndConsumeMotionEvent(
+            size_t samplesToAppendBeforeDispatch = 0,
+            size_t samplesToAppendAfterDispatch = 0);
+};
+
+TEST_F(InputPublisherAndConsumerTest, GetChannel_ReturnsTheChannel) {
+    EXPECT_EQ(serverChannel.get(), mPublisher->getChannel().get());
+    EXPECT_EQ(clientChannel.get(), mConsumer->getChannel().get());
+}
+
+void InputPublisherAndConsumerTest::Initialize() {
+    status_t status;
+
+    status = mPublisher->initialize();
+    ASSERT_EQ(OK, status)
+            << "publisher initialize should return OK";
+
+    status = mConsumer->initialize();
+    ASSERT_EQ(OK, status)
+            << "consumer initialize should return OK";
+}
+
+void InputPublisherAndConsumerTest::PublishAndConsumeKeyEvent() {
+    status_t status;
+
+    const int32_t deviceId = 1;
+    const int32_t source = AINPUT_SOURCE_KEYBOARD;
+    const int32_t action = AKEY_EVENT_ACTION_DOWN;
+    const int32_t flags = AKEY_EVENT_FLAG_FROM_SYSTEM;
+    const int32_t keyCode = AKEYCODE_ENTER;
+    const int32_t scanCode = 13;
+    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+    const int32_t repeatCount = 1;
+    const nsecs_t downTime = 3;
+    const nsecs_t eventTime = 4;
+
+    status = mPublisher->publishKeyEvent(deviceId, source, action, flags,
+            keyCode, scanCode, metaState, repeatCount, downTime, eventTime);
+    ASSERT_EQ(OK, status)
+            << "publisher publishKeyEvent should return OK";
+
+    status = mPublisher->sendDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher sendDispatchSignal should return OK";
+
+    status = mConsumer->receiveDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer receiveDispatchSignal should return OK";
+
+    InputEvent* event;
+    status = mConsumer->consume(& mEventFactory, & event);
+    ASSERT_EQ(OK, status)
+            << "consumer consume should return OK";
+
+    ASSERT_TRUE(event != NULL)
+            << "consumer should have returned non-NULL event";
+    ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, event->getType())
+            << "consumer should have returned a key event";
+
+    KeyEvent* keyEvent = static_cast<KeyEvent*>(event);
+    EXPECT_EQ(deviceId, keyEvent->getDeviceId());
+    EXPECT_EQ(source, keyEvent->getSource());
+    EXPECT_EQ(action, keyEvent->getAction());
+    EXPECT_EQ(flags, keyEvent->getFlags());
+    EXPECT_EQ(keyCode, keyEvent->getKeyCode());
+    EXPECT_EQ(scanCode, keyEvent->getScanCode());
+    EXPECT_EQ(metaState, keyEvent->getMetaState());
+    EXPECT_EQ(repeatCount, keyEvent->getRepeatCount());
+    EXPECT_EQ(downTime, keyEvent->getDownTime());
+    EXPECT_EQ(eventTime, keyEvent->getEventTime());
+
+    status = mConsumer->sendFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer sendFinishedSignal should return OK";
+
+    status = mPublisher->receiveFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher receiveFinishedSignal should return OK";
+
+    status = mPublisher->reset();
+    ASSERT_EQ(OK, status)
+            << "publisher reset should return OK";
+}
+
+void InputPublisherAndConsumerTest::PublishAndConsumeMotionEvent(
+        size_t samplesToAppendBeforeDispatch, size_t samplesToAppendAfterDispatch) {
+    status_t status;
+
+    const int32_t deviceId = 1;
+    const int32_t source = AINPUT_SOURCE_TOUCHSCREEN;
+    const int32_t action = AMOTION_EVENT_ACTION_MOVE;
+    const int32_t flags = AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED;
+    const int32_t edgeFlags = AMOTION_EVENT_EDGE_FLAG_TOP;
+    const int32_t metaState = AMETA_ALT_LEFT_ON | AMETA_ALT_ON;
+    const float xOffset = -10;
+    const float yOffset = -20;
+    const float xPrecision = 0.25;
+    const float yPrecision = 0.5;
+    const nsecs_t downTime = 3;
+    const size_t pointerCount = 3;
+    const int32_t pointerIds[pointerCount] = { 2, 0, 1 };
+
+    Vector<nsecs_t> sampleEventTimes;
+    Vector<PointerCoords> samplePointerCoords;
+
+    for (size_t i = 0; i <= samplesToAppendAfterDispatch + samplesToAppendBeforeDispatch; i++) {
+        sampleEventTimes.push(i + 10);
+        for (size_t j = 0; j < pointerCount; j++) {
+            samplePointerCoords.push();
+            samplePointerCoords.editTop().x = 100 * i + j;
+            samplePointerCoords.editTop().y = 200 * i + j;
+            samplePointerCoords.editTop().pressure = 0.5 * i + j;
+            samplePointerCoords.editTop().size = 0.7 * i + j;
+            samplePointerCoords.editTop().touchMajor = 1.5 * i + j;
+            samplePointerCoords.editTop().touchMinor = 1.7 * i + j;
+            samplePointerCoords.editTop().toolMajor = 2.5 * i + j;
+            samplePointerCoords.editTop().toolMinor = 2.7 * i + j;
+            samplePointerCoords.editTop().orientation = 3.5 * i + j;
+        }
+    }
+
+    status = mPublisher->publishMotionEvent(deviceId, source, action, flags, edgeFlags,
+            metaState, xOffset, yOffset, xPrecision, yPrecision,
+            downTime, sampleEventTimes[0], pointerCount, pointerIds, samplePointerCoords.array());
+    ASSERT_EQ(OK, status)
+            << "publisher publishMotionEvent should return OK";
+
+    for (size_t i = 0; i < samplesToAppendBeforeDispatch; i++) {
+        size_t sampleIndex = i + 1;
+        status = mPublisher->appendMotionSample(sampleEventTimes[sampleIndex],
+                samplePointerCoords.array() + sampleIndex * pointerCount);
+        ASSERT_EQ(OK, status)
+                << "publisher appendMotionEvent should return OK";
+    }
+
+    status = mPublisher->sendDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher sendDispatchSignal should return OK";
+
+    for (size_t i = 0; i < samplesToAppendAfterDispatch; i++) {
+        size_t sampleIndex = i + 1 + samplesToAppendBeforeDispatch;
+        status = mPublisher->appendMotionSample(sampleEventTimes[sampleIndex],
+                samplePointerCoords.array() + sampleIndex * pointerCount);
+        ASSERT_EQ(OK, status)
+                << "publisher appendMotionEvent should return OK";
+    }
+
+    status = mConsumer->receiveDispatchSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer receiveDispatchSignal should return OK";
+
+    InputEvent* event;
+    status = mConsumer->consume(& mEventFactory, & event);
+    ASSERT_EQ(OK, status)
+            << "consumer consume should return OK";
+
+    ASSERT_TRUE(event != NULL)
+            << "consumer should have returned non-NULL event";
+    ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, event->getType())
+            << "consumer should have returned a motion event";
+
+    size_t lastSampleIndex = samplesToAppendBeforeDispatch + samplesToAppendAfterDispatch;
+
+    MotionEvent* motionEvent = static_cast<MotionEvent*>(event);
+    EXPECT_EQ(deviceId, motionEvent->getDeviceId());
+    EXPECT_EQ(source, motionEvent->getSource());
+    EXPECT_EQ(action, motionEvent->getAction());
+    EXPECT_EQ(flags, motionEvent->getFlags());
+    EXPECT_EQ(edgeFlags, motionEvent->getEdgeFlags());
+    EXPECT_EQ(metaState, motionEvent->getMetaState());
+    EXPECT_EQ(xPrecision, motionEvent->getXPrecision());
+    EXPECT_EQ(yPrecision, motionEvent->getYPrecision());
+    EXPECT_EQ(downTime, motionEvent->getDownTime());
+    EXPECT_EQ(sampleEventTimes[lastSampleIndex], motionEvent->getEventTime());
+    EXPECT_EQ(pointerCount, motionEvent->getPointerCount());
+    EXPECT_EQ(lastSampleIndex, motionEvent->getHistorySize());
+
+    for (size_t i = 0; i < pointerCount; i++) {
+        SCOPED_TRACE(i);
+        EXPECT_EQ(pointerIds[i], motionEvent->getPointerId(i));
+    }
+
+    for (size_t sampleIndex = 0; sampleIndex < lastSampleIndex; sampleIndex++) {
+        SCOPED_TRACE(sampleIndex);
+        EXPECT_EQ(sampleEventTimes[sampleIndex],
+                motionEvent->getHistoricalEventTime(sampleIndex));
+        for (size_t i = 0; i < pointerCount; i++) {
+            SCOPED_TRACE(i);
+            size_t offset = sampleIndex * pointerCount + i;
+            EXPECT_EQ(samplePointerCoords[offset].x,
+                    motionEvent->getHistoricalRawX(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].y,
+                    motionEvent->getHistoricalRawY(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].x + xOffset,
+                    motionEvent->getHistoricalX(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].y + yOffset,
+                    motionEvent->getHistoricalY(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].pressure,
+                    motionEvent->getHistoricalPressure(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].size,
+                    motionEvent->getHistoricalSize(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].touchMajor,
+                    motionEvent->getHistoricalTouchMajor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].touchMinor,
+                    motionEvent->getHistoricalTouchMinor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].toolMajor,
+                    motionEvent->getHistoricalToolMajor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].toolMinor,
+                    motionEvent->getHistoricalToolMinor(i, sampleIndex));
+            EXPECT_EQ(samplePointerCoords[offset].orientation,
+                    motionEvent->getHistoricalOrientation(i, sampleIndex));
+        }
+    }
+
+    SCOPED_TRACE(lastSampleIndex);
+    EXPECT_EQ(sampleEventTimes[lastSampleIndex], motionEvent->getEventTime());
+    for (size_t i = 0; i < pointerCount; i++) {
+        SCOPED_TRACE(i);
+        size_t offset = lastSampleIndex * pointerCount + i;
+        EXPECT_EQ(samplePointerCoords[offset].x, motionEvent->getRawX(i));
+        EXPECT_EQ(samplePointerCoords[offset].y, motionEvent->getRawY(i));
+        EXPECT_EQ(samplePointerCoords[offset].x + xOffset, motionEvent->getX(i));
+        EXPECT_EQ(samplePointerCoords[offset].y + yOffset, motionEvent->getY(i));
+        EXPECT_EQ(samplePointerCoords[offset].pressure, motionEvent->getPressure(i));
+        EXPECT_EQ(samplePointerCoords[offset].size, motionEvent->getSize(i));
+        EXPECT_EQ(samplePointerCoords[offset].touchMajor, motionEvent->getTouchMajor(i));
+        EXPECT_EQ(samplePointerCoords[offset].touchMinor, motionEvent->getTouchMinor(i));
+        EXPECT_EQ(samplePointerCoords[offset].toolMajor, motionEvent->getToolMajor(i));
+        EXPECT_EQ(samplePointerCoords[offset].toolMinor, motionEvent->getToolMinor(i));
+        EXPECT_EQ(samplePointerCoords[offset].orientation, motionEvent->getOrientation(i));
+    }
+
+    status = mConsumer->sendFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "consumer sendFinishedSignal should return OK";
+
+    status = mPublisher->receiveFinishedSignal();
+    ASSERT_EQ(OK, status)
+            << "publisher receiveFinishedSignal should return OK";
+
+    status = mPublisher->reset();
+    ASSERT_EQ(OK, status)
+            << "publisher reset should return OK";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishKeyEvent_WhenNotReset_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    status = mPublisher->publishKeyEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+    ASSERT_EQ(OK, status)
+            << "publisher publishKeyEvent should return OK first time";
+
+    status = mPublisher->publishKeyEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher publishKeyEvent should return INVALID_OPERATION because "
+                    "the publisher was not reset";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenNotReset_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = 1;
+    int32_t pointerIds[pointerCount] = { 0 };
+    PointerCoords pointerCoords[pointerCount] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status)
+            << "publisher publishMotionEvent should return OK";
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher publishMotionEvent should return INVALID_OPERATION because ";
+                    "the publisher was not reset";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountLessThan1_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = 0;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(BAD_VALUE, status)
+            << "publisher publishMotionEvent should return BAD_VALUE";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMotionEvent_WhenPointerCountGreaterThanMax_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS + 1;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+            pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(BAD_VALUE, status)
+            << "publisher publishMotionEvent should return BAD_VALUE";
+}
+
+TEST_F(InputPublisherAndConsumerTest, PublishMultipleEvents_EndToEnd) {
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeKeyEvent());
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenCalledBeforeDispatchSignal_AppendsSamples) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent(3, 0));
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenCalledAfterDispatchSignalAndNotConsumed_AppendsSamples) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+    ASSERT_NO_FATAL_FAILURE(PublishAndConsumeMotionEvent(0, 4));
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenNoMotionEventPublished_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    PointerCoords pointerCoords[1];
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher appendMotionSample should return INVALID_OPERATION";
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenPublishedMotionEventIsNotAMove_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_DOWN,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status);
+
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(INVALID_OPERATION, status)
+            << "publisher appendMotionSample should return INVALID_OPERATION";
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenAlreadyConsumed_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status);
+
+    status = mPublisher->sendDispatchSignal();
+    ASSERT_EQ(OK, status);
+
+    status = mConsumer->receiveDispatchSignal();
+    ASSERT_EQ(OK, status);
+
+    InputEvent* event;
+    status = mConsumer->consume(& mEventFactory, & event);
+    ASSERT_EQ(OK, status);
+
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(status_t(FAILED_TRANSACTION), status)
+            << "publisher appendMotionSample should return FAILED_TRANSACTION";
+}
+
+TEST_F(InputPublisherAndConsumerTest, AppendMotionSample_WhenBufferFull_ReturnsError) {
+    status_t status;
+    ASSERT_NO_FATAL_FAILURE(Initialize());
+
+    const size_t pointerCount = MAX_POINTERS;
+    int32_t pointerIds[pointerCount];
+    PointerCoords pointerCoords[pointerCount];
+
+    status = mPublisher->publishMotionEvent(0, 0, AMOTION_EVENT_ACTION_MOVE,
+            0, 0, 0, 0, 0, 0, 0, 0, 0, pointerCount, pointerIds, pointerCoords);
+    ASSERT_EQ(OK, status);
+
+    for (int count = 1;; count++) {
+        ASSERT_LT(count, 100000) << "should eventually reach OOM";
+
+        status = mPublisher->appendMotionSample(0, pointerCoords);
+        if (status != OK) {
+            ASSERT_GT(count, 12) << "should be able to add at least a dozen samples";
+            ASSERT_EQ(NO_MEMORY, status)
+                    << "publisher appendMotionSample should return NO_MEMORY when buffer is full";
+            break;
+        }
+    }
+
+    status = mPublisher->appendMotionSample(0, pointerCoords);
+    ASSERT_EQ(NO_MEMORY, status)
+            << "publisher appendMotionSample should return NO_MEMORY persistently until reset";
+}
+
+} // namespace android
diff --git a/libs/ui/tests/region/Android.mk b/libs/ui/tests/region/Android.mk
new file mode 100644
index 0000000..6cc4a5a
--- /dev/null
+++ b/libs/ui/tests/region/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	region.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+    libui
+
+LOCAL_MODULE:= test-region
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/ui/tests/region.cpp b/libs/ui/tests/region/region.cpp
similarity index 100%
rename from libs/ui/tests/region.cpp
rename to libs/ui/tests/region/region.cpp
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index afecdcb..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..d2dd6eb
--- /dev/null
+++ b/libs/utils/Looper.cpp
@@ -0,0 +1,379 @@
+//
+// 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>
+#include <sys/epoll.h>
+
+
+namespace android {
+
+// 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;
+
+static pthread_once_t gTLSOnce = PTHREAD_ONCE_INIT;
+static pthread_key_t gTLSKey = 0;
+
+Looper::Looper(bool allowNonCallbacks) :
+        mAllowNonCallbacks(allowNonCallbacks),
+        mResponseIndex(0) {
+    mEpollFd = epoll_create(EPOLL_SIZE_HINT);
+    LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance.  errno=%d", errno);
+
+    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);
+
+    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);
+}
+
+Looper::~Looper() {
+    close(mWakeReadPipeFd);
+    close(mWakeWritePipeFd);
+    close(mEpollFd);
+}
+
+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
+    struct epoll_event eventItems[EPOLL_MAX_EVENTS];
+    int eventCount = epoll_wait(mEpollFd, eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
+    if (eventCount < 0) {
+        if (errno == EINTR) {
+            return ALOOPER_POLL_WAKE;
+        }
+
+        LOGW("Poll failed with an unexpected error, errno=%d", errno);
+        return ALOOPER_POLL_ERROR;
+    }
+
+    if (eventCount == 0) {
+#if DEBUG_POLL_AND_WAKE
+        LOGD("%p ~ pollOnce - timeout", this);
+#endif
+        return ALOOPER_POLL_TIMEOUT;
+    }
+
+    int result = ALOOPER_POLL_WAKE;
+    mResponses.clear();
+    mResponseIndex = 0;
+
+#if DEBUG_POLL_AND_WAKE
+    LOGD("%p ~ pollOnce - handling events from %d fds", this, eventCount);
+#endif
+    bool acquiredLock = false;
+    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) {
+#if DEBUG_POLL_AND_WAKE
+                LOGD("%p ~ pollOnce - awoken", this);
+#endif
+                char buffer[16];
+                ssize_t nRead;
+                do {
+                    nRead = read(mWakeReadPipeFd, buffer, sizeof(buffer));
+                } while ((nRead == -1 && errno == EINTR) || nRead == sizeof(buffer));
+            } 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;
+
+                Response response;
+                response.events = events;
+                response.request = mRequests.valueAt(requestIndex);
+                mResponses.push(response);
+            } else {
+                LOGW("Ignoring unexpected epoll events 0x%x on fd %d that is "
+                        "no longer registered.", epollEvents, fd);
+            }
+        }
+    }
+    if (acquiredLock) {
+        mLock.unlock();
+    }
+
+    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
+
+    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);
+        }
+    }
+}
+
+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
+
+    int epollEvents = 0;
+    if (events & ALOOPER_EVENT_INPUT) epollEvents |= EPOLLIN;
+    if (events & ALOOPER_EVENT_OUTPUT) epollEvents |= EPOLLOUT;
+    if (events & ALOOPER_EVENT_ERROR) epollEvents |= EPOLLERR;
+    if (events & ALOOPER_EVENT_HANGUP) epollEvents |= EPOLLHUP;
+
+    if (epollEvents == 0) {
+        LOGE("Invalid attempt to set a callback with no selected poll events.");
+        return -1;
+    }
+
+    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;
+        }
+    }
+
+    { // 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
+    return 1;
+}
+
+int Looper::removeFd(int fd) {
+#if DEBUG_CALLBACKS
+    LOGD("%p ~ removeFd - fd=%d", this, fd);
+#endif
+
+    { // 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);
+    } // request lock
+    return 1;
+}
+
+} // namespace android
diff --git a/libs/utils/ObbFile.cpp b/libs/utils/ObbFile.cpp
new file mode 100644
index 0000000..e170ab8
--- /dev/null
+++ b/libs/utils/ObbFile.cpp
@@ -0,0 +1,344 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define LOG_TAG "ObbFile"
+#include <utils/Log.h>
+#include <utils/ObbFile.h>
+
+//#define DEBUG 1
+
+#define kFooterTagSize 8  /* last two 32-bit integers */
+
+#define kFooterMinSize 25 /* 32-bit signature version (4 bytes)
+                           * 32-bit package version (4 bytes)
+                           * 32-bit flags (4 bytes)
+                           * 32-bit package name size (4-bytes)
+                           * >=1-character package name (1 byte)
+                           * 32-bit footer size (4 bytes)
+                           * 32-bit footer marker (4 bytes)
+                           */
+
+#define kMaxBufSize    32768 /* Maximum file read buffer */
+
+#define kSignature     0x01059983U /* ObbFile signature */
+
+#define kSigVersion    1 /* We only know about signature version 1 */
+
+/* offsets in version 1 of the header */
+#define kPackageVersionOffset 4
+#define kFlagsOffset          8
+#define kPackageNameLenOffset 12
+#define kPackageNameOffset    16
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
+
+/*
+ * Work around situations where off_t is 64-bit and use off64_t in
+ * situations where it's 32-bit.
+ */
+#ifdef OFF_T_IS_64_BIT
+#define my_lseek64 lseek
+typedef off_t my_off64_t;
+#else
+#define my_lseek64 lseek64
+typedef off64_t my_off64_t;
+#endif
+
+namespace android {
+
+ObbFile::ObbFile() :
+        mPackageName(""),
+        mVersion(-1),
+        mFlags(0)
+{
+}
+
+ObbFile::~ObbFile() {
+}
+
+bool ObbFile::readFrom(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_RDONLY);
+    if (fd < 0) {
+        LOGW("couldn't open file %s: %s", filename, strerror(errno));
+        goto out;
+    }
+    success = readFrom(fd);
+    close(fd);
+
+    if (!success) {
+        LOGW("failed to read from %s (fd=%d)\n", filename, fd);
+    }
+
+out:
+    return success;
+}
+
+bool ObbFile::readFrom(int fd)
+{
+    if (fd < 0) {
+        LOGW("attempt to read from invalid fd\n");
+        return false;
+    }
+
+    return parseObbFile(fd);
+}
+
+bool ObbFile::parseObbFile(int fd)
+{
+    my_off64_t fileLength = my_lseek64(fd, 0, SEEK_END);
+
+    if (fileLength < kFooterMinSize) {
+        if (fileLength < 0) {
+            LOGW("error seeking in ObbFile: %s\n", strerror(errno));
+        } else {
+            LOGW("file is only %lld (less than %d minimum)\n", fileLength, kFooterMinSize);
+        }
+        return false;
+    }
+
+    ssize_t actual;
+    size_t footerSize;
+
+    {
+        my_lseek64(fd, fileLength - kFooterTagSize, SEEK_SET);
+
+        char *footer = new char[kFooterTagSize];
+        actual = TEMP_FAILURE_RETRY(read(fd, footer, kFooterTagSize));
+        if (actual != kFooterTagSize) {
+            LOGW("couldn't read footer signature: %s\n", strerror(errno));
+            return false;
+        }
+
+        unsigned int fileSig = get4LE((unsigned char*)footer + sizeof(int32_t));
+        if (fileSig != kSignature) {
+            LOGW("footer didn't match magic string (expected 0x%08x; got 0x%08x)\n",
+                    kSignature, fileSig);
+            return false;
+        }
+
+        footerSize = get4LE((unsigned char*)footer);
+        if (footerSize > (size_t)fileLength - kFooterTagSize
+                || footerSize > kMaxBufSize) {
+            LOGW("claimed footer size is too large (0x%08zx; file size is 0x%08llx)\n",
+                    footerSize, fileLength);
+            return false;
+        }
+
+        if (footerSize < (kFooterMinSize - kFooterTagSize)) {
+            LOGW("claimed footer size is too small (0x%zx; minimum size is 0x%x)\n",
+                    footerSize, kFooterMinSize - kFooterTagSize);
+            return false;
+        }
+    }
+
+    my_off64_t fileOffset = fileLength - footerSize - kFooterTagSize;
+    if (my_lseek64(fd, fileOffset, SEEK_SET) != fileOffset) {
+        LOGW("seek %lld failed: %s\n", fileOffset, strerror(errno));
+        return false;
+    }
+
+    mFooterStart = fileOffset;
+
+    char* scanBuf = (char*)malloc(footerSize);
+    if (scanBuf == NULL) {
+        LOGW("couldn't allocate scanBuf: %s\n", strerror(errno));
+        return false;
+    }
+
+    actual = TEMP_FAILURE_RETRY(read(fd, scanBuf, footerSize));
+    // readAmount is guaranteed to be less than kMaxBufSize
+    if (actual != (ssize_t)footerSize) {
+        LOGI("couldn't read ObbFile footer: %s\n", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+#ifdef DEBUG
+    for (int i = 0; i < footerSize; ++i) {
+        LOGI("char: 0x%02x", scanBuf[i]);
+    }
+#endif
+
+    uint32_t sigVersion = get4LE((unsigned char*)scanBuf);
+    if (sigVersion != kSigVersion) {
+        LOGW("Unsupported ObbFile version %d\n", sigVersion);
+        free(scanBuf);
+        return false;
+    }
+
+    mVersion = (int32_t) get4LE((unsigned char*)scanBuf + kPackageVersionOffset);
+    mFlags = (int32_t) get4LE((unsigned char*)scanBuf + kFlagsOffset);
+
+    uint32_t packageNameLen = get4LE((unsigned char*)scanBuf + kPackageNameLenOffset);
+    if (packageNameLen <= 0
+            || packageNameLen > (footerSize - kPackageNameOffset)) {
+        LOGW("bad ObbFile package name length (0x%04x; 0x%04x possible)\n",
+                packageNameLen, footerSize - kPackageNameOffset);
+        free(scanBuf);
+        return false;
+    }
+
+    char* packageName = reinterpret_cast<char*>(scanBuf + kPackageNameOffset);
+    mPackageName = String8(const_cast<char*>(packageName), packageNameLen);
+
+    free(scanBuf);
+
+#ifdef DEBUG
+    LOGI("Obb scan succeeded: packageName=%s, version=%d\n", mPackageName.string(), mVersion);
+#endif
+
+    return true;
+}
+
+bool ObbFile::writeTo(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_WRONLY);
+    if (fd < 0) {
+        goto out;
+    }
+    success = writeTo(fd);
+    close(fd);
+
+out:
+    if (!success) {
+        LOGW("failed to write to %s: %s\n", filename, strerror(errno));
+    }
+    return success;
+}
+
+bool ObbFile::writeTo(int fd)
+{
+    if (fd < 0) {
+        return false;
+    }
+
+    my_lseek64(fd, 0, SEEK_END);
+
+    if (mPackageName.size() == 0 || mVersion == -1) {
+        LOGW("tried to write uninitialized ObbFile data");
+        return false;
+    }
+
+    unsigned char intBuf[sizeof(uint32_t)+1];
+    memset(&intBuf, 0, sizeof(intBuf));
+
+    put4LE(intBuf, kSigVersion);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write signature version: %s", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, mVersion);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package version");
+        return false;
+    }
+
+    put4LE(intBuf, mFlags);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package version");
+        return false;
+    }
+
+    size_t packageNameLen = mPackageName.size();
+    put4LE(intBuf, packageNameLen);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write package name length: %s", strerror(errno));
+        return false;
+    }
+
+    if (write(fd, mPackageName.string(), packageNameLen) != (ssize_t)packageNameLen) {
+        LOGW("couldn't write package name: %s", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, kPackageNameOffset + packageNameLen);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write footer size: %s", strerror(errno));
+        return false;
+    }
+
+    put4LE(intBuf, kSignature);
+    if (write(fd, &intBuf, sizeof(uint32_t)) != (ssize_t)sizeof(uint32_t)) {
+        LOGW("couldn't write footer magic signature: %s", strerror(errno));
+        return false;
+    }
+
+    return true;
+}
+
+bool ObbFile::removeFrom(const char* filename)
+{
+    int fd;
+    bool success = false;
+
+    fd = ::open(filename, O_RDWR);
+    if (fd < 0) {
+        goto out;
+    }
+    success = removeFrom(fd);
+    close(fd);
+
+out:
+    if (!success) {
+        LOGW("failed to remove signature from %s: %s\n", filename, strerror(errno));
+    }
+    return success;
+}
+
+bool ObbFile::removeFrom(int fd)
+{
+    if (fd < 0) {
+        return false;
+    }
+
+    if (!readFrom(fd)) {
+        return false;
+    }
+
+    ftruncate(fd, mFooterStart);
+
+    return true;
+}
+
+}
diff --git a/libs/utils/Pool.cpp b/libs/utils/Pool.cpp
new file mode 100644
index 0000000..8f18cb9
--- /dev/null
+++ b/libs/utils/Pool.cpp
@@ -0,0 +1,37 @@
+//
+// Copyright 2010 The Android Open Source Project
+//
+// A simple memory pool.
+//
+#define LOG_TAG "Pool"
+
+//#define LOG_NDEBUG 0
+
+#include <cutils/log.h>
+#include <utils/Pool.h>
+
+#include <stdlib.h>
+
+namespace android {
+
+// TODO Provide a real implementation of a pool.  This is just a stub for initial development.
+
+PoolImpl::PoolImpl(size_t objSize) :
+    mObjSize(objSize) {
+}
+
+PoolImpl::~PoolImpl() {
+}
+
+void* PoolImpl::allocImpl() {
+    void* ptr = malloc(mObjSize);
+    LOG_ALWAYS_FATAL_IF(ptr == NULL, "Cannot allocate new pool object.");
+    return ptr;
+}
+
+void PoolImpl::freeImpl(void* obj) {
+    LOG_ALWAYS_FATAL_IF(obj == NULL, "Caller attempted to free NULL pool object.");
+    return free(obj);
+}
+
+} // namespace android
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7e0f881..8345cc3 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1934,8 +1934,8 @@
         ssize_t offset = getEntry(package, t, e, &mParams, &type, &entry, &typeClass);
         if (offset <= 0) {
             if (offset < 0) {
-                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %d: 0x%08x\n",
-                        resID, t, e, (int)ip, (int)offset);
+                LOGW("Failure getting entry for 0x%08x (t=%d e=%d) in package %zd (error %d)\n",
+                        resID, t, e, ip, (int)offset);
                 return offset;
             }
             continue;
@@ -4178,6 +4178,9 @@
                             case ResTable_config::SCREENSIZE_LARGE:
                                 printf(" (large)");
                                 break;
+                            case ResTable_config::SCREENSIZE_XLARGE:
+                                printf(" (xlarge)");
+                                break;
                         }
                         printf(" lng=%d",
                                 type->config.screenLayout&ResTable_config::MASK_SCREENLONG);
diff --git a/libs/utils/StopWatch.cpp b/libs/utils/StopWatch.cpp
index 68a1c52..b5dda2f 100644
--- a/libs/utils/StopWatch.cpp
+++ b/libs/utils/StopWatch.cpp
@@ -30,10 +30,9 @@
 
 
 StopWatch::StopWatch(const char *name, int clock, uint32_t flags)
-    :   mName(name), mClock(clock), mFlags(flags),
-        mStartTime(0), mNumLaps(0)
+    :   mName(name), mClock(clock), mFlags(flags)
 {
-    mStartTime = systemTime(mClock);
+    reset();
 }
 
 StopWatch::~StopWatch()
@@ -72,6 +71,12 @@
     return systemTime(mClock) - mStartTime;
 }
 
+void StopWatch::reset()
+{
+    mNumLaps = 0;
+    mStartTime = systemTime(mClock);
+}
+
 
 /*****************************************************************************/
 
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/utils/StreamingZipInflater.cpp
new file mode 100644
index 0000000..7ebde78
--- /dev/null
+++ b/libs/utils/StreamingZipInflater.cpp
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "szipinf"
+#include <utils/Log.h>
+
+#include <utils/FileMap.h>
+#include <utils/StreamingZipInflater.h>
+#include <string.h>
+#include <stddef.h>
+#include <assert.h>
+
+static inline size_t min_of(size_t a, size_t b) { return (a < b) ? a : b; }
+
+using namespace android;
+
+/*
+ * Streaming access to compressed asset data in an open fd
+ */
+StreamingZipInflater::StreamingZipInflater(int fd, off_t compDataStart,
+        size_t uncompSize, size_t compSize) {
+    mFd = fd;
+    mDataMap = NULL;
+    mInFileStart = compDataStart;
+    mOutTotalSize = uncompSize;
+    mInTotalSize = compSize;
+
+    mInBufSize = StreamingZipInflater::INPUT_CHUNK_SIZE;
+    mInBuf = new uint8_t[mInBufSize];
+
+    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
+    mOutBuf = new uint8_t[mOutBufSize];
+
+    initInflateState();
+}
+
+/*
+ * Streaming access to compressed data held in an mmapped region of memory
+ */
+StreamingZipInflater::StreamingZipInflater(FileMap* dataMap, size_t uncompSize) {
+    mFd = -1;
+    mDataMap = dataMap;
+    mOutTotalSize = uncompSize;
+    mInTotalSize = dataMap->getDataLength();
+
+    mInBuf = (uint8_t*) dataMap->getDataPtr();
+    mInBufSize = mInTotalSize;
+
+    mOutBufSize = StreamingZipInflater::OUTPUT_CHUNK_SIZE;
+    mOutBuf = new uint8_t[mOutBufSize];
+
+    initInflateState();
+}
+
+StreamingZipInflater::~StreamingZipInflater() {
+    // tear down the in-flight zip state just in case
+    ::inflateEnd(&mInflateState);
+
+    if (mDataMap == NULL) {
+        delete [] mInBuf;
+    }
+    delete [] mOutBuf;
+}
+
+void StreamingZipInflater::initInflateState() {
+    LOGD("Initializing inflate state");
+
+    memset(&mInflateState, 0, sizeof(mInflateState));
+    mInflateState.zalloc = Z_NULL;
+    mInflateState.zfree = Z_NULL;
+    mInflateState.opaque = Z_NULL;
+    mInflateState.next_in = (Bytef*)mInBuf;
+    mInflateState.next_out = (Bytef*) mOutBuf;
+    mInflateState.avail_out = mOutBufSize;
+    mInflateState.data_type = Z_UNKNOWN;
+
+    mOutLastDecoded = mOutDeliverable = mOutCurPosition = 0;
+    mInNextChunkOffset = 0;
+    mStreamNeedsInit = true;
+
+    if (mDataMap == NULL) {
+        ::lseek(mFd, mInFileStart, SEEK_SET);
+        mInflateState.avail_in = 0; // set when a chunk is read in
+    } else {
+        mInflateState.avail_in = mInBufSize;
+    }
+}
+
+/*
+ * Basic approach:
+ *
+ * 1. If we have undelivered uncompressed data, send it.  At this point
+ *    either we've satisfied the request, or we've exhausted the available
+ *    output data in mOutBuf.
+ *
+ * 2. While we haven't sent enough data to satisfy the request:
+ *    0. if the request is for more data than exists, bail.
+ *    a. if there is no input data to decode, read some into the input buffer
+ *       and readjust the z_stream input pointers
+ *    b. point the output to the start of the output buffer and decode what we can
+ *    c. deliver whatever output data we can
+ */
+ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
+    uint8_t* dest = (uint8_t*) outBuf;
+    size_t bytesRead = 0;
+    size_t toRead = min_of(count, size_t(mOutTotalSize - mOutCurPosition));
+    while (toRead > 0) {
+        // First, write from whatever we already have decoded and ready to go
+        size_t deliverable = min_of(toRead, mOutLastDecoded - mOutDeliverable);
+        if (deliverable > 0) {
+            if (outBuf != NULL) memcpy(dest, mOutBuf + mOutDeliverable, deliverable);
+            mOutDeliverable += deliverable;
+            mOutCurPosition += deliverable;
+            dest += deliverable;
+            bytesRead += deliverable;
+            toRead -= deliverable;
+        }
+
+        // need more data?  time to decode some.
+        if (toRead > 0) {
+            // if we don't have any data to decode, read some in.  If we're working
+            // from mmapped data this won't happen, because the clipping to total size
+            // will prevent reading off the end of the mapped input chunk.
+            if (mInflateState.avail_in == 0) {
+                int err = readNextChunk();
+                if (err < 0) {
+                    LOGE("Unable to access asset data: %d", err);
+                    if (!mStreamNeedsInit) {
+                        ::inflateEnd(&mInflateState);
+                        initInflateState();
+                    }
+                    return -1;
+                }
+            }
+            // we know we've drained whatever is in the out buffer now, so just
+            // start from scratch there, reading all the input we have at present.
+            mInflateState.next_out = (Bytef*) mOutBuf;
+            mInflateState.avail_out = mOutBufSize;
+
+            /*
+            LOGD("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
+                    mInflateState.avail_in, mInflateState.avail_out,
+                    mInflateState.next_in, mInflateState.next_out);
+            */
+            int result = Z_OK;
+            if (mStreamNeedsInit) {
+                LOGI("Initializing zlib to inflate");
+                result = inflateInit2(&mInflateState, -MAX_WBITS);
+                mStreamNeedsInit = false;
+            }
+            if (result == Z_OK) result = ::inflate(&mInflateState, Z_SYNC_FLUSH);
+            if (result < 0) {
+                // Whoops, inflation failed
+                LOGE("Error inflating asset: %d", result);
+                ::inflateEnd(&mInflateState);
+                initInflateState();
+                return -1;
+            } else {
+                if (result == Z_STREAM_END) {
+                    // we know we have to have reached the target size here and will
+                    // not try to read any further, so just wind things up.
+                    ::inflateEnd(&mInflateState);
+                }
+
+                // Note how much data we got, and off we go
+                mOutDeliverable = 0;
+                mOutLastDecoded = mOutBufSize - mInflateState.avail_out;
+            }
+        }
+    }
+    return bytesRead;
+}
+
+int StreamingZipInflater::readNextChunk() {
+    assert(mDataMap == NULL);
+
+    if (mInNextChunkOffset < mInTotalSize) {
+        size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
+        if (toRead > 0) {
+            ssize_t didRead = ::read(mFd, mInBuf, toRead);
+            //LOGD("Reading input chunk, size %08x didread %08x", toRead, didRead);
+            if (didRead < 0) {
+                // TODO: error
+                LOGE("Error reading asset data");
+                return didRead;
+            } else {
+                mInNextChunkOffset += didRead;
+                mInflateState.next_in = (Bytef*) mInBuf;
+                mInflateState.avail_in = didRead;
+            }
+        }
+    }
+    return 0;
+}
+
+// seeking backwards requires uncompressing fom the beginning, so is very
+// expensive.  seeking forwards only requires uncompressing from the current
+// position to the destination.
+off_t StreamingZipInflater::seekAbsolute(off_t absoluteInputPosition) {
+    if (absoluteInputPosition < mOutCurPosition) {
+        // rewind and reprocess the data from the beginning
+        if (!mStreamNeedsInit) {
+            ::inflateEnd(&mInflateState);
+        }
+        initInflateState();
+        read(NULL, absoluteInputPosition);
+    } else if (absoluteInputPosition > mOutCurPosition) {
+        read(NULL, absoluteInputPosition - mOutCurPosition);
+    }
+    // else if the target position *is* our current position, do nothing
+    return absoluteInputPosition;
+}
diff --git a/libs/utils/String8.cpp b/libs/utils/String8.cpp
index 636cd83..1c4f80c 100644
--- a/libs/utils/String8.cpp
+++ b/libs/utils/String8.cpp
@@ -301,8 +301,9 @@
 
 status_t String8::setTo(const char* other)
 {
+    const char *newString = allocFromUTF8(other, strlen(other));
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF8(other, strlen(other));
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -311,8 +312,9 @@
 
 status_t String8::setTo(const char* other, size_t len)
 {
+    const char *newString = allocFromUTF8(other, len);
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF8(other, len);
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -321,8 +323,9 @@
 
 status_t String8::setTo(const char16_t* other, size_t len)
 {
+    const char *newString = allocFromUTF16(other, len);
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF16(other, len);
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -331,8 +334,9 @@
 
 status_t String8::setTo(const char32_t* other, size_t len)
 {
+    const char *newString = allocFromUTF32(other, len);
     SharedBuffer::bufferFromData(mString)->release();
-    mString = allocFromUTF32(other, len);
+    mString = newString;
     if (mString) return NO_ERROR;
 
     mString = getEmptyString();
@@ -368,6 +372,27 @@
     return real_append(other, otherLen);
 }
 
+status_t String8::appendFormat(const char* fmt, ...)
+{
+    va_list ap;
+    va_start(ap, fmt);
+
+    int result = NO_ERROR;
+    int n = vsnprintf(NULL, 0, fmt, ap);
+    if (n != 0) {
+        size_t oldLength = length();
+        char* buf = lockBuffer(oldLength + n);
+        if (buf) {
+            vsnprintf(buf + oldLength, n + 1, fmt, ap);
+        } else {
+            result = NO_MEMORY;
+        }
+    }
+
+    va_end(ap);
+    return result;
+}
+
 status_t String8::real_append(const char* other, size_t otherLen)
 {
     const size_t myLen = bytes();
@@ -407,15 +432,16 @@
     if (size != this->size()) {
         SharedBuffer* buf = SharedBuffer::bufferFromData(mString)
             ->editResize(size+1);
-        if (buf) {
-            char* str = (char*)buf->data();
-            str[size] = 0;
-            mString = str;
-            return NO_ERROR;
+        if (! buf) {
+            return NO_MEMORY;
         }
+
+        char* str = (char*)buf->data();
+        str[size] = 0;
+        mString = str;
     }
-    
-    return NO_MEMORY;
+
+    return NO_ERROR;
 }
 
 ssize_t String8::find(const char* other, size_t start) const
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 2b1f490..f6c55e4 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -21,6 +21,7 @@
 #include <utils/Log.h>
 
 #include <cutils/sched_policy.h>
+#include <cutils/properties.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -57,13 +58,27 @@
 // ----------------------------------------------------------------------------
 
 /*
- * Create and run a new thead.
+ * Create and run a new thread.
  *
  * We create it "detached", so it cleans up after itself.
  */
 
 typedef void* (*android_pthread_entry)(void*);
 
+static pthread_once_t gDoSchedulingGroupOnce = PTHREAD_ONCE_INIT;
+static bool gDoSchedulingGroup = true;
+
+static void checkDoSchedulingGroup(void) {
+    char buf[PROPERTY_VALUE_MAX];
+    int len = property_get("debug.sys.noschedgroups", buf, "");
+    if (len > 0) {
+        int temp;
+        if (sscanf(buf, "%d", &temp) == 1) {
+            gDoSchedulingGroup = temp == 0;
+        }
+    }
+}
+
 struct thread_data_t {
     thread_func_t   entryFunction;
     void*           userData;
@@ -79,6 +94,15 @@
         char * name = t->threadName;
         delete t;
         setpriority(PRIO_PROCESS, 0, prio);
+        pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+        if (gDoSchedulingGroup) {
+            if (prio >= ANDROID_PRIORITY_BACKGROUND) {
+                set_sched_policy(androidGetTid(), SP_BACKGROUND);
+            } else {
+                set_sched_policy(androidGetTid(), SP_FOREGROUND);
+            }
+        }
+        
         if (name) {
 #if defined(HAVE_PRCTL)
             // Mac OS doesn't have this, and we build libutil for the host too
@@ -287,9 +311,12 @@
     }
 
 #if defined(HAVE_PTHREADS)
-    if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
-                                      SP_BACKGROUND : SP_FOREGROUND)) {
-        return PERMISSION_DENIED;
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (set_sched_policy(tid, (grp == ANDROID_TGROUP_BG_NONINTERACT) ?
+                                          SP_BACKGROUND : SP_FOREGROUND)) {
+            return PERMISSION_DENIED;
+        }
     }
 #endif
     
@@ -303,10 +330,13 @@
 #if defined(HAVE_PTHREADS)
     int lasterr = 0;
 
-    if (pri >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_BACKGROUND);
-    } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
-        rc = set_sched_policy(tid, SP_FOREGROUND);
+    pthread_once(&gDoSchedulingGroupOnce, checkDoSchedulingGroup);
+    if (gDoSchedulingGroup) {
+        if (pri >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_BACKGROUND);
+        } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
+            rc = set_sched_policy(tid, SP_FOREGROUND);
+        }
     }
 
     if (rc) {
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index 0322af7..289c826 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -108,13 +108,7 @@
 
 ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index)
 {
-    if (index > size())
-        return BAD_INDEX;
-    void* where = _grow(index, vector.size());
-    if (where) {
-        _do_copy(where, vector.arrayImpl(), vector.size());
-    }
-    return where ? index : (ssize_t)NO_MEMORY;
+    return insertArrayAt(vector.arrayImpl(), index, vector.size());
 }
 
 ssize_t VectorImpl::appendVector(const VectorImpl& vector)
@@ -122,6 +116,22 @@
     return insertVectorAt(vector, size());
 }
 
+ssize_t VectorImpl::insertArrayAt(const void* array, size_t index, size_t length)
+{
+    if (index > size())
+        return BAD_INDEX;
+    void* where = _grow(index, length);
+    if (where) {
+        _do_copy(where, array, length);
+    }
+    return where ? index : (ssize_t)NO_MEMORY;
+}
+
+ssize_t VectorImpl::appendArray(const void* array, size_t length)
+{
+    return insertArrayAt(array, size(), length);
+}
+
 ssize_t VectorImpl::insertAt(size_t index, size_t numItems)
 {
     return insertAt(0, index, numItems);
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/utils/ZipFileCRO.cpp
index 45f6c8b..16b219c 100644
--- a/libs/utils/ZipFileCRO.cpp
+++ b/libs/utils/ZipFileCRO.cpp
@@ -39,8 +39,8 @@
 }
 
 bool ZipFileCRO_getEntryInfo(ZipFileCRO zipToken, ZipEntryRO entryToken,
-        int* pMethod, long* pUncompLen,
-        long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
+        int* pMethod, size_t* pUncompLen,
+        size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) {
     ZipFileRO* zip = (ZipFileRO*)zipToken;
     ZipEntryRO entry = (ZipEntryRO)entryToken;
     return zip->getEntryInfo(entry, pMethod, pUncompLen, pCompLen, pOffset,
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index 6c701dd..2d53136 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -29,6 +29,22 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <assert.h>
+#include <unistd.h>
+
+/*
+ * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
+ * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
+ * not already defined, then define it here.
+ */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) ({         \
+    typeof (exp) _rc;                      \
+    do {                                   \
+        _rc = (exp);                       \
+    } while (_rc == -1 && errno == EINTR); \
+    _rc; })
+#endif
 
 using namespace android;
 
@@ -38,6 +54,7 @@
 #define kEOCDSignature      0x06054b50
 #define kEOCDLen            22
 #define kEOCDNumEntries     8               // offset to #of entries in file
+#define kEOCDSize           12              // size of the central directory
 #define kEOCDFileOffset     16              // offset to central directory
 
 #define kMaxCommentLen      65535           // longest possible in ushort
@@ -90,9 +107,8 @@
 status_t ZipFileRO::open(const char* zipFileName)
 {
     int fd = -1;
-    off_t length;
 
-    assert(mFileMap == NULL);
+    assert(mDirectoryMap == NULL);
 
     /*
      * Open and map the specified file.
@@ -103,172 +119,238 @@
         return NAME_NOT_FOUND;
     }
 
-    length = lseek(fd, 0, SEEK_END);
-    if (length < 0) {
+    mFileLength = lseek(fd, 0, SEEK_END);
+    if (mFileLength < kEOCDLen) {
         close(fd);
         return UNKNOWN_ERROR;
     }
 
-    mFileMap = new FileMap();
-    if (mFileMap == NULL) {
-        close(fd);
-        return NO_MEMORY;
+    if (mFileName != NULL) {
+        free(mFileName);
     }
-    if (!mFileMap->create(zipFileName, fd, 0, length, true)) {
-        LOGW("Unable to map '%s': %s\n", zipFileName, strerror(errno));
-        close(fd);
-        return UNKNOWN_ERROR;
-    }
+    mFileName = strdup(zipFileName);
 
     mFd = fd;
 
     /*
-     * Got it mapped, verify it and create data structures for fast access.
+     * Find the Central Directory and store its size and number of entries.
+     */
+    if (!mapCentralDirectory()) {
+        goto bail;
+    }
+
+    /*
+     * Verify Central Directory and create data structures for fast access.
      */
     if (!parseZipArchive()) {
-        mFileMap->release();
-        mFileMap = NULL;
-        return UNKNOWN_ERROR;
+        goto bail;
     }
 
     return OK;
+
+bail:
+    free(mFileName);
+    mFileName = NULL;
+    close(fd);
+    return UNKNOWN_ERROR;
 }
 
 /*
  * Parse the Zip archive, verifying its contents and initializing internal
  * data structures.
  */
+bool ZipFileRO::mapCentralDirectory(void)
+{
+    size_t readAmount = kMaxEOCDSearch;
+    if (readAmount > (size_t) mFileLength)
+        readAmount = mFileLength;
+
+    unsigned char* scanBuf = (unsigned char*) malloc(readAmount);
+    if (scanBuf == NULL) {
+        LOGW("couldn't allocate scanBuf: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Make sure this is a Zip archive.
+     */
+    if (lseek(mFd, 0, SEEK_SET) != 0) {
+        LOGW("seek to start failed: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    ssize_t actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, sizeof(int32_t)));
+    if (actual != (ssize_t) sizeof(int32_t)) {
+        LOGI("couldn't read first signature from zip archive: %s", strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    {
+        unsigned int header = get4LE(scanBuf);
+        if (header == kEOCDSignature) {
+            LOGI("Found Zip archive, but it looks empty\n");
+            free(scanBuf);
+            return false;
+        } else if (header != kLFHSignature) {
+            LOGV("Not a Zip archive (found 0x%08x)\n", val);
+            free(scanBuf);
+            return false;
+        }
+    }
+
+    /*
+     * Perform the traditional EOCD snipe hunt.
+     *
+     * We're searching for the End of Central Directory magic number,
+     * which appears at the start of the EOCD block.  It's followed by
+     * 18 bytes of EOCD stuff and up to 64KB of archive comment.  We
+     * need to read the last part of the file into a buffer, dig through
+     * it to find the magic number, parse some values out, and use those
+     * to determine the extent of the CD.
+     *
+     * We start by pulling in the last part of the file.
+     */
+    off_t searchStart = mFileLength - readAmount;
+
+    if (lseek(mFd, searchStart, SEEK_SET) != searchStart) {
+        LOGW("seek %ld failed: %s\n",  (long) searchStart, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+    actual = TEMP_FAILURE_RETRY(read(mFd, scanBuf, readAmount));
+    if (actual != (ssize_t) readAmount) {
+        LOGW("Zip: read %zd failed: %s\n", readAmount, strerror(errno));
+        free(scanBuf);
+        return false;
+    }
+
+    /*
+     * Scan backward for the EOCD magic.  In an archive without a trailing
+     * comment, we'll find it on the first try.  (We may want to consider
+     * doing an initial minimal read; if we don't find it, retry with a
+     * second read as above.)
+     */
+    int i;
+    for (i = readAmount - kEOCDLen; i >= 0; i--) {
+        if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
+            LOGV("+++ Found EOCD at buf+%d\n", i);
+            break;
+        }
+    }
+    if (i < 0) {
+        LOGD("Zip: EOCD not found, %s is not zip\n", mFileName);
+        free(scanBuf);
+        return false;
+    }
+
+    off_t eocdOffset = searchStart + i;
+    const unsigned char* eocdPtr = scanBuf + i;
+
+    assert(eocdOffset < mFileLength);
+
+    /*
+     * Grab the CD offset and size, and the number of entries in the
+     * archive. After that, we can release our EOCD hunt buffer.
+     */
+    unsigned int numEntries = get2LE(eocdPtr + kEOCDNumEntries);
+    unsigned int dirSize = get4LE(eocdPtr + kEOCDSize);
+    unsigned int dirOffset = get4LE(eocdPtr + kEOCDFileOffset);
+    free(scanBuf);
+
+    // Verify that they look reasonable.
+    if ((long long) dirOffset + (long long) dirSize > (long long) eocdOffset) {
+        LOGW("bad offsets (dir %ld, size %u, eocd %ld)\n",
+            (long) dirOffset, dirSize, (long) eocdOffset);
+        return false;
+    }
+    if (numEntries == 0) {
+        LOGW("empty archive?\n");
+        return false;
+    }
+
+    LOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
+        numEntries, dirSize, dirOffset);
+
+    mDirectoryMap = new FileMap();
+    if (mDirectoryMap == NULL) {
+        LOGW("Unable to create directory map: %s", strerror(errno));
+        return false;
+    }
+
+    if (!mDirectoryMap->create(mFileName, mFd, dirOffset, dirSize, true)) {
+        LOGW("Unable to map '%s' (%zd to %zd): %s\n", mFileName,
+                dirOffset, dirOffset + dirSize, strerror(errno));
+        return false;
+    }
+
+    mNumEntries = numEntries;
+    mDirectoryOffset = dirOffset;
+
+    return true;
+}
+
 bool ZipFileRO::parseZipArchive(void)
 {
-#define CHECK_OFFSET(_off) {                                                \
-        if ((unsigned int) (_off) >= maxOffset) {                           \
-            LOGE("ERROR: bad offset %u (max %d): %s\n",                     \
-                (unsigned int) (_off), maxOffset, #_off);                   \
-            goto bail;                                                      \
-        }                                                                   \
-    }
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
-    const unsigned char* ptr;
-    size_t length = mFileMap->getDataLength();
     bool result = false;
-    unsigned int i, numEntries, cdOffset;
-    unsigned int val;
-
-    /*
-     * The first 4 bytes of the file will either be the local header
-     * signature for the first file (kLFHSignature) or, if the archive doesn't
-     * have any files in it, the end-of-central-directory signature
-     * (kEOCDSignature).
-     */
-    val = get4LE(basePtr);
-    if (val == kEOCDSignature) {
-        LOGI("Found Zip archive, but it looks empty\n");
-        goto bail;
-    } else if (val != kLFHSignature) {
-        LOGV("Not a Zip archive (found 0x%08x)\n", val);
-        goto bail;
-    }
-
-    /*
-     * Find the EOCD.  We'll find it immediately unless they have a file
-     * comment.
-     */
-    ptr = basePtr + length - kEOCDLen;
-
-    while (ptr >= basePtr) {
-        if (*ptr == (kEOCDSignature & 0xff) && get4LE(ptr) == kEOCDSignature)
-            break;
-        ptr--;
-    }
-    if (ptr < basePtr) {
-        LOGI("Could not find end-of-central-directory in Zip\n");
-        goto bail;
-    }
-
-    /*
-     * There are two interesting items in the EOCD block: the number of
-     * entries in the file, and the file offset of the start of the
-     * central directory.
-     *
-     * (There's actually a count of the #of entries in this file, and for
-     * all files which comprise a spanned archive, but for our purposes
-     * we're only interested in the current file.  Besides, we expect the
-     * two to be equivalent for our stuff.)
-     */
-    numEntries = get2LE(ptr + kEOCDNumEntries);
-    cdOffset = get4LE(ptr + kEOCDFileOffset);
-
-    /* valid offsets are [0,EOCD] */
-    unsigned int maxOffset;
-    maxOffset = (ptr - basePtr) +1;
-
-    LOGV("+++ numEntries=%d cdOffset=%d\n", numEntries, cdOffset);
-    if (numEntries == 0 || cdOffset >= length) {
-        LOGW("Invalid entries=%d offset=%d (len=%zd)\n",
-            numEntries, cdOffset, length);
-        goto bail;
-    }
+    const unsigned char* cdPtr = (const unsigned char*) mDirectoryMap->getDataPtr();
+    size_t cdLength = mDirectoryMap->getDataLength();
+    int numEntries = mNumEntries;
 
     /*
      * Create hash table.  We have a minimum 75% load factor, possibly as
      * low as 50% after we round off to a power of 2.
      */
-    mNumEntries = numEntries;
-    mHashTableSize = roundUpPower2(1 + ((numEntries * 4) / 3));
-    mHashTable = (HashEntry*) calloc(1, sizeof(HashEntry) * mHashTableSize);
+    mHashTableSize = roundUpPower2(1 + (numEntries * 4) / 3);
+    mHashTable = (HashEntry*) calloc(mHashTableSize, sizeof(HashEntry));
 
     /*
      * Walk through the central directory, adding entries to the hash
      * table.
      */
-    ptr = basePtr + cdOffset;
-    for (i = 0; i < numEntries; i++) {
-        unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
-        const unsigned char* localHdr;
-        unsigned int hash;
-
+    const unsigned char* ptr = cdPtr;
+    for (int i = 0; i < numEntries; i++) {
         if (get4LE(ptr) != kCDESignature) {
             LOGW("Missed a central dir sig (at %d)\n", i);
             goto bail;
         }
-        if (ptr + kCDELen > basePtr + length) {
+        if (ptr + kCDELen > cdPtr + cdLength) {
             LOGW("Ran off the end (at %d)\n", i);
             goto bail;
         }
 
-        localHdrOffset = get4LE(ptr + kCDELocalOffset);
-        CHECK_OFFSET(localHdrOffset);
+        long localHdrOffset = (long) get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset >= mDirectoryOffset) {
+            LOGW("bad LFH offset %ld at entry %d\n", localHdrOffset, i);
+            goto bail;
+        }
+
+        unsigned int fileNameLen, extraLen, commentLen, hash;
+
         fileNameLen = get2LE(ptr + kCDENameLen);
         extraLen = get2LE(ptr + kCDEExtraLen);
         commentLen = get2LE(ptr + kCDECommentLen);
 
-        //LOGV("+++ %d: localHdr=%d fnl=%d el=%d cl=%d\n",
-        //    i, localHdrOffset, fileNameLen, extraLen, commentLen);
-        //LOGV(" '%.*s'\n", fileNameLen, ptr + kCDELen);
-
         /* add the CDE filename to the hash table */
         hash = computeHash((const char*)ptr + kCDELen, fileNameLen);
         addToHash((const char*)ptr + kCDELen, fileNameLen, hash);
 
-        localHdr = basePtr + localHdrOffset;
-        if (get4LE(localHdr) != kLFHSignature) {
-            LOGW("Bad offset to local header: %d (at %d)\n",
-                localHdrOffset, i);
+        ptr += kCDELen + fileNameLen + extraLen + commentLen;
+        if ((size_t)(ptr - cdPtr) > cdLength) {
+            LOGW("bad CD advance (%d vs %zd) at entry %d\n",
+                (int) (ptr - cdPtr), cdLength, i);
             goto bail;
         }
-
-        ptr += kCDELen + fileNameLen + extraLen + commentLen;
-        CHECK_OFFSET(ptr - basePtr);
     }
-
+    LOGV("+++ zip good scan %d entries\n", numEntries);
     result = true;
 
 bail:
     return result;
-#undef CHECK_OFFSET
 }
 
-
 /*
  * Simple string hash function for non-null-terminated strings.
  */
@@ -315,7 +397,7 @@
             memcmp(mHashTable[ent].name, fileName, nameLen) == 0)
         {
             /* match */
-            return (ZipEntryRO) (ent + kZipEntryAdj);
+            return (ZipEntryRO)(long)(ent + kZipEntryAdj);
         }
 
         ent = (ent + 1) & (mHashTableSize-1);
@@ -354,20 +436,24 @@
  * Returns "false" if the offsets to the fields or the contents of the fields
  * appear to be bogus.
  */
-bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
-    long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
+bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen,
+    size_t* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const
 {
-    int ent = entryToIndex(entry);
+    bool ret = false;
+
+    const int ent = entryToIndex(entry);
     if (ent < 0)
         return false;
 
+    HashEntry hashEntry = mHashTable[ent];
+
     /*
      * Recover the start of the central directory entry from the filename
-     * pointer.
+     * pointer.  The filename is the first entry past the fixed-size data,
+     * so we can just subtract back from that.
      */
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
-    const unsigned char* ptr = (const unsigned char*) mHashTable[ent].name;
-    size_t zipLength = mFileMap->getDataLength();
+    const unsigned char* ptr = (const unsigned char*) hashEntry.name;
+    off_t cdOffset = mDirectoryOffset;
 
     ptr -= kCDELen;
 
@@ -380,48 +466,78 @@
     if (pCrc32 != NULL)
         *pCrc32 = get4LE(ptr + kCDECRC);
 
+    size_t compLen = get4LE(ptr + kCDECompLen);
+    if (pCompLen != NULL)
+        *pCompLen = compLen;
+    size_t uncompLen = get4LE(ptr + kCDEUncompLen);
+    if (pUncompLen != NULL)
+        *pUncompLen = uncompLen;
+
     /*
-     * We need to make sure that the lengths are not so large that somebody
-     * trying to map the compressed or uncompressed data runs off the end
-     * of the mapped region.
+     * If requested, determine the offset of the start of the data.  All we
+     * have is the offset to the Local File Header, which is variable size,
+     * so we have to read the contents of the struct to figure out where
+     * the actual data starts.
+     *
+     * We also need to make sure that the lengths are not so large that
+     * somebody trying to map the compressed or uncompressed data runs
+     * off the end of the mapped region.
+     *
+     * Note we don't verify compLen/uncompLen if they don't request the
+     * dataOffset, because dataOffset is expensive to determine.  However,
+     * if they don't have the file offset, they're not likely to be doing
+     * anything with the contents.
      */
-    unsigned long localHdrOffset = get4LE(ptr + kCDELocalOffset);
-    if (localHdrOffset + kLFHLen >= zipLength) {
-        LOGE("ERROR: bad local hdr offset in zip\n");
-        return false;
-    }
-    const unsigned char* localHdr = basePtr + localHdrOffset;
-    off_t dataOffset = localHdrOffset + kLFHLen
-        + get2LE(localHdr + kLFHNameLen) + get2LE(localHdr + kLFHExtraLen);
-    if ((unsigned long) dataOffset >= zipLength) {
-        LOGE("ERROR: bad data offset in zip\n");
-        return false;
-    }
-
-    if (pCompLen != NULL) {
-        *pCompLen = get4LE(ptr + kCDECompLen);
-        if (*pCompLen < 0 || (size_t)(dataOffset + *pCompLen) >= zipLength) {
-            LOGE("ERROR: bad compressed length in zip\n");
-            return false;
-        }
-    }
-    if (pUncompLen != NULL) {
-        *pUncompLen = get4LE(ptr + kCDEUncompLen);
-        if (*pUncompLen < 0) {
-            LOGE("ERROR: negative uncompressed length in zip\n");
-            return false;
-        }
-        if (method == kCompressStored &&
-            (size_t)(dataOffset + *pUncompLen) >= zipLength)
-        {
-            LOGE("ERROR: bad uncompressed length in zip\n");
-            return false;
-        }
-    }
-
     if (pOffset != NULL) {
+        long localHdrOffset = get4LE(ptr + kCDELocalOffset);
+        if (localHdrOffset + kLFHLen >= cdOffset) {
+            LOGE("ERROR: bad local hdr offset in zip\n");
+            return false;
+        }
+
+        unsigned char lfhBuf[kLFHLen];
+        if (lseek(mFd, localHdrOffset, SEEK_SET) != localHdrOffset) {
+            LOGW("failed seeking to lfh at offset %ld\n", localHdrOffset);
+            return false;
+        }
+        ssize_t actual =
+            TEMP_FAILURE_RETRY(read(mFd, lfhBuf, sizeof(lfhBuf)));
+        if (actual != sizeof(lfhBuf)) {
+            LOGW("failed reading lfh from offset %ld\n", localHdrOffset);
+            return false;
+        }
+
+        if (get4LE(lfhBuf) != kLFHSignature) {
+            LOGW("didn't find signature at start of lfh, offset=%ld (got 0x%08lx, expected 0x%08x)\n",
+                localHdrOffset, get4LE(lfhBuf), kLFHSignature);
+            return false;
+        }
+
+        off_t dataOffset = localHdrOffset + kLFHLen
+            + get2LE(lfhBuf + kLFHNameLen) + get2LE(lfhBuf + kLFHExtraLen);
+        if (dataOffset >= cdOffset) {
+            LOGW("bad data offset %ld in zip\n", (long) dataOffset);
+            return false;
+        }
+
+        /* check lengths */
+        if ((off_t)(dataOffset + compLen) > cdOffset) {
+            LOGW("bad compressed length in zip (%ld + %zd > %ld)\n",
+                (long) dataOffset, compLen, (long) cdOffset);
+            return false;
+        }
+
+        if (method == kCompressStored &&
+            (off_t)(dataOffset + uncompLen) > cdOffset)
+        {
+            LOGE("ERROR: bad uncompressed length in zip (%ld + %zd > %ld)\n",
+                (long) dataOffset, uncompLen, (long) cdOffset);
+            return false;
+        }
+
         *pOffset = dataOffset;
     }
+
     return true;
 }
 
@@ -457,14 +573,14 @@
      */
 
     FileMap* newMap;
-    long compLen;
+    size_t compLen;
     off_t offset;
 
     if (!getEntryInfo(entry, NULL, NULL, &compLen, &offset, NULL, NULL))
         return NULL;
 
     newMap = new FileMap();
-    if (!newMap->create(mFileMap->getFileName(), mFd, offset, compLen, true)) {
+    if (!newMap->create(mFileName, mFd, offset, compLen, true)) {
         newMap->release();
         return NULL;
     }
@@ -480,19 +596,26 @@
  */
 bool ZipFileRO::uncompressEntry(ZipEntryRO entry, void* buffer) const
 {
-    const int kSequentialMin = 32768;
+    const size_t kSequentialMin = 32768;
     bool result = false;
     int ent = entryToIndex(entry);
     if (ent < 0)
         return -1;
 
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
     int method;
-    long uncompLen, compLen;
+    size_t uncompLen, compLen;
     off_t offset;
+    const unsigned char* ptr;
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
+    FileMap* file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
+
+    ptr = (const unsigned char*) file->getDataPtr();
+
     /*
      * Experiment with madvise hint.  When we want to uncompress a file,
      * we pull some stuff out of the central dir entry and then hit a
@@ -507,17 +630,17 @@
      * pair of system calls are negated by a reduction in page faults.
      */
     if (compLen > kSequentialMin)
-        mFileMap->advise(FileMap::SEQUENTIAL);
+        file->advise(FileMap::SEQUENTIAL);
 
     if (method == kCompressStored) {
-        memcpy(buffer, basePtr + offset, uncompLen);
+        memcpy(buffer, ptr, uncompLen);
     } else {
-        if (!inflateBuffer(buffer, basePtr + offset, uncompLen, compLen))
+        if (!inflateBuffer(buffer, ptr, uncompLen, compLen))
             goto bail;
     }
 
     if (compLen > kSequentialMin)
-        mFileMap->advise(FileMap::NORMAL);
+        file->advise(FileMap::NORMAL);
 
     result = true;
 
@@ -537,29 +660,34 @@
     if (ent < 0)
         return -1;
 
-    const unsigned char* basePtr = (const unsigned char*)mFileMap->getDataPtr();
     int method;
-    long uncompLen, compLen;
+    size_t uncompLen, compLen;
     off_t offset;
+    const unsigned char* ptr;
 
     getEntryInfo(entry, &method, &uncompLen, &compLen, &offset, NULL, NULL);
 
-    if (method == kCompressStored) {
-        ssize_t actual;
+    const FileMap* file = createEntryFileMap(entry);
+    if (file == NULL) {
+        goto bail;
+    }
 
-        actual = write(fd, basePtr + offset, uncompLen);
+    ptr = (const unsigned char*) file->getDataPtr();
+
+    if (method == kCompressStored) {
+        ssize_t actual = write(fd, ptr, uncompLen);
         if (actual < 0) {
             LOGE("Write failed: %s\n", strerror(errno));
             goto bail;
-        } else if (actual != uncompLen) {
-            LOGE("Partial write during uncompress (%d of %ld)\n",
-                (int)actual, uncompLen);
+        } else if ((size_t) actual != uncompLen) {
+            LOGE("Partial write during uncompress (%zd of %zd)\n",
+                (size_t)actual, (size_t)uncompLen);
             goto bail;
         } else {
             LOGI("+++ successful write\n");
         }
     } else {
-        if (!inflateBuffer(fd, basePtr+offset, uncompLen, compLen))
+        if (!inflateBuffer(fd, ptr, uncompLen, compLen))
             goto bail;
     }
 
@@ -573,7 +701,7 @@
  * Uncompress "deflate" data from one buffer to another.
  */
 /*static*/ bool ZipFileRO::inflateBuffer(void* outBuf, const void* inBuf,
-    long uncompLen, long compLen)
+    size_t uncompLen, size_t compLen)
 {
     bool result = false;
     z_stream zstream;
@@ -582,7 +710,7 @@
     /*
      * Initialize the zlib stream struct.
      */
-	memset(&zstream, 0, sizeof(zstream));
+    memset(&zstream, 0, sizeof(zstream));
     zstream.zalloc = Z_NULL;
     zstream.zfree = Z_NULL;
     zstream.opaque = Z_NULL;
@@ -592,10 +720,10 @@
     zstream.avail_out = uncompLen;
     zstream.data_type = Z_UNKNOWN;
 
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
+    /*
+     * Use the undocumented "negative window bits" feature to tell zlib
+     * that there's no zlib header waiting for it.
+     */
     zerr = inflateInit2(&zstream, -MAX_WBITS);
     if (zerr != Z_OK) {
         if (zerr == Z_VERSION_ERROR) {
@@ -619,8 +747,8 @@
     }
 
     /* paranoia */
-    if ((long) zstream.total_out != uncompLen) {
-        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+    if (zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %zd)\n",
             zstream.total_out, uncompLen);
         goto z_bail;
     }
@@ -638,10 +766,10 @@
  * Uncompress "deflate" data from one buffer to an open file descriptor.
  */
 /*static*/ bool ZipFileRO::inflateBuffer(int fd, const void* inBuf,
-    long uncompLen, long compLen)
+    size_t uncompLen, size_t compLen)
 {
     bool result = false;
-    const int kWriteBufSize = 32768;
+    const size_t kWriteBufSize = 32768;
     unsigned char writeBuf[kWriteBufSize];
     z_stream zstream;
     int zerr;
@@ -649,7 +777,7 @@
     /*
      * Initialize the zlib stream struct.
      */
-	memset(&zstream, 0, sizeof(zstream));
+    memset(&zstream, 0, sizeof(zstream));
     zstream.zalloc = Z_NULL;
     zstream.zfree = Z_NULL;
     zstream.opaque = Z_NULL;
@@ -659,10 +787,10 @@
     zstream.avail_out = sizeof(writeBuf);
     zstream.data_type = Z_UNKNOWN;
 
-	/*
-	 * Use the undocumented "negative window bits" feature to tell zlib
-	 * that there's no zlib header waiting for it.
-	 */
+    /*
+     * Use the undocumented "negative window bits" feature to tell zlib
+     * that there's no zlib header waiting for it.
+     */
     zerr = inflateInit2(&zstream, -MAX_WBITS);
     if (zerr != Z_OK) {
         if (zerr == Z_VERSION_ERROR) {
@@ -708,8 +836,8 @@
     assert(zerr == Z_STREAM_END);       /* other errors should've been caught */
 
     /* paranoia */
-    if ((long) zstream.total_out != uncompLen) {
-        LOGW("Size mismatch on inflated file (%ld vs %ld)\n",
+    if (zstream.total_out != uncompLen) {
+        LOGW("Size mismatch on inflated file (%ld vs %zd)\n",
             zstream.total_out, uncompLen);
         goto z_bail;
     }
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
new file mode 100644
index 0000000..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..afc92f8
--- /dev/null
+++ b/libs/utils/tests/Looper_test.cpp
@@ -0,0 +1,433 @@
+//
+// 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_WhenEventsIsZero_ReturnsError) {
+    Pipe pipe;
+    int result = mLooper->addFd(pipe.receiveFd, 0, 0, NULL, NULL);
+
+    EXPECT_EQ(-1, result)
+            << "addFd should return -1 because arguments were invalid";
+}
+
+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..29bb70a
--- /dev/null
+++ b/libs/utils/tests/ObbFile_test.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "ObbFile_test"
+#include <utils/Log.h>
+#include <utils/ObbFile.h>
+#include <utils/RefBase.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+#include <fcntl.h>
+
+namespace android {
+
+#define TEST_FILENAME "/test.obb"
+
+class ObbFileTest : public testing::Test {
+protected:
+    sp<ObbFile> mObbFile;
+    char* mExternalStorage;
+    char* mFileName;
+
+    virtual void SetUp() {
+        mObbFile = new ObbFile();
+        mExternalStorage = getenv("EXTERNAL_STORAGE");
+
+        const int totalLen = strlen(mExternalStorage) + strlen(TEST_FILENAME) + 1;
+        mFileName = new char[totalLen];
+        snprintf(mFileName, totalLen, "%s%s", mExternalStorage, TEST_FILENAME);
+
+        int fd = ::open(mFileName, O_CREAT | O_TRUNC);
+        if (fd < 0) {
+            FAIL() << "Couldn't create " << mFileName << " for tests";
+        }
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(ObbFileTest, ReadFailure) {
+    EXPECT_FALSE(mObbFile->readFrom(-1))
+            << "No failure on invalid file descriptor";
+}
+
+TEST_F(ObbFileTest, WriteThenRead) {
+    const char* packageName = "com.example.obbfile";
+    const int32_t versionNum = 1;
+
+    mObbFile->setPackageName(String8(packageName));
+    mObbFile->setVersion(versionNum);
+
+    EXPECT_TRUE(mObbFile->writeTo(mFileName))
+            << "couldn't write to fake .obb file";
+
+    mObbFile = new ObbFile();
+
+    EXPECT_TRUE(mObbFile->readFrom(mFileName))
+            << "couldn't read from fake .obb file";
+
+    EXPECT_EQ(versionNum, mObbFile->getVersion())
+            << "version didn't come out the same as it went in";
+    const char* currentPackageName = mObbFile->getPackageName().string();
+    EXPECT_STREQ(packageName, currentPackageName)
+            << "package name didn't come out the same as it went in";
+}
+
+}
diff --git a/libs/utils/tests/String8_test.cpp b/libs/utils/tests/String8_test.cpp
new file mode 100644
index 0000000..c42c68d
--- /dev/null
+++ b/libs/utils/tests/String8_test.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "String8_test"
+#include <utils/Log.h>
+#include <utils/String8.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+class String8Test : public testing::Test {
+protected:
+    virtual void SetUp() {
+    }
+
+    virtual void TearDown() {
+    }
+};
+
+TEST_F(String8Test, Cstr) {
+    String8 tmp("Hello, world!");
+
+    EXPECT_STREQ(tmp.string(), "Hello, world!");
+}
+
+TEST_F(String8Test, OperatorPlus) {
+    String8 src1("Hello, ");
+
+    // Test adding String8 + const char*
+    const char* ccsrc2 = "world!";
+    String8 dst1 = src1 + ccsrc2;
+    EXPECT_STREQ(dst1.string(), "Hello, world!");
+    EXPECT_STREQ(src1.string(), "Hello, ");
+    EXPECT_STREQ(ccsrc2, "world!");
+
+    // Test adding String8 + String8
+    String8 ssrc2("world!");
+    String8 dst2 = src1 + ssrc2;
+    EXPECT_STREQ(dst2.string(), "Hello, world!");
+    EXPECT_STREQ(src1.string(), "Hello, ");
+    EXPECT_STREQ(ssrc2.string(), "world!");
+}
+
+TEST_F(String8Test, OperatorPlusEquals) {
+    String8 src1("My voice");
+
+    // Testing String8 += String8
+    String8 src2(" is my passport.");
+    src1 += src2;
+    EXPECT_STREQ(src1.string(), "My voice is my passport.");
+    EXPECT_STREQ(src2.string(), " is my passport.");
+
+    // Adding const char* to the previous string.
+    const char* src3 = " Verify me.";
+    src1 += src3;
+    EXPECT_STREQ(src1.string(), "My voice is my passport. Verify me.");
+    EXPECT_STREQ(src2.string(), " is my passport.");
+    EXPECT_STREQ(src3, " Verify me.");
+}
+
+}
diff --git a/libs/utils/tests/TestHelpers.h b/libs/utils/tests/TestHelpers.h
new file mode 100644
index 0000000..d8e985e
--- /dev/null
+++ b/libs/utils/tests/TestHelpers.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TESTHELPERS_H
+#define TESTHELPERS_H
+
+#include <utils/threads.h>
+
+namespace android {
+
+class Pipe {
+public:
+    int sendFd;
+    int receiveFd;
+
+    Pipe() {
+        int fds[2];
+        ::pipe(fds);
+
+        receiveFd = fds[0];
+        sendFd = fds[1];
+    }
+
+    ~Pipe() {
+        if (sendFd != -1) {
+            ::close(sendFd);
+        }
+
+        if (receiveFd != -1) {
+            ::close(receiveFd);
+        }
+    }
+
+    status_t writeSignal() {
+        ssize_t nWritten = ::write(sendFd, "*", 1);
+        return nWritten == 1 ? 0 : -errno;
+    }
+
+    status_t readSignal() {
+        char buf[1];
+        ssize_t nRead = ::read(receiveFd, buf, 1);
+        return nRead == 1 ? 0 : nRead == 0 ? -EPIPE : -errno;
+    }
+};
+
+class DelayedTask : public Thread {
+    int mDelayMillis;
+
+public:
+    DelayedTask(int delayMillis) : mDelayMillis(delayMillis) { }
+
+protected:
+    virtual ~DelayedTask() { }
+
+    virtual void doTask() = 0;
+
+    virtual bool threadLoop() {
+        usleep(mDelayMillis * 1000);
+        doTask();
+        return false;
+    }
+};
+
+} // namespace android
+
+#endif // TESTHELPERS_H
diff --git a/opengl/include/EGL/egl.h b/opengl/include/EGL/egl.h
index c269976..99ea342 100644
--- a/opengl/include/EGL/egl.h
+++ b/opengl/include/EGL/egl.h
@@ -1,7 +1,7 @@
 /* -*- mode: c; tab-width: 8; -*- */
 /* vi: set sw=4 ts=8: */
 /* Reference version of egl.h for EGL 1.4.
- * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ * $Revision: 9356 $ on $Date: 2009-10-21 02:52:25 -0700 (Wed, 21 Oct 2009) $
  */
 
 /*
@@ -109,7 +109,6 @@
 #define EGL_NATIVE_RENDERABLE		0x302D
 #define EGL_NATIVE_VISUAL_ID		0x302E
 #define EGL_NATIVE_VISUAL_TYPE		0x302F
-#define EGL_PRESERVED_RESOURCES		0x3030
 #define EGL_SAMPLES			0x3031
 #define EGL_SAMPLE_BUFFERS		0x3032
 #define EGL_SURFACE_TYPE		0x3033
diff --git a/opengl/include/EGL/eglext.h b/opengl/include/EGL/eglext.h
index 545fd0e..1ffcd56 100644
--- a/opengl/include/EGL/eglext.h
+++ b/opengl/include/EGL/eglext.h
@@ -6,7 +6,7 @@
 #endif
 
 /*
-** Copyright (c) 2007-2009 The Khronos Group Inc.
+** Copyright (c) 2007-2010 The Khronos Group Inc.
 **
 ** Permission is hereby granted, free of charge, to any person obtaining a
 ** copy of this software and/or associated documentation files (the
@@ -34,8 +34,8 @@
 
 /* Header file version number */
 /* Current version at http://www.khronos.org/registry/egl/ */
-/* $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $ */
-#define EGL_EGLEXT_VERSION 3
+/* $Revision: 11249 $ on $Date: 2010-05-05 09:54:28 -0700 (Wed, 05 May 2010) $ */
+#define EGL_EGLEXT_VERSION 5
 
 #ifndef EGL_KHR_config_attribs
 #define EGL_KHR_config_attribs 1
@@ -120,6 +120,36 @@
 #define EGL_GL_RENDERBUFFER_KHR			0x30B9	/* eglCreateImageKHR target */
 #endif
 
+#ifndef EGL_KHR_reusable_sync
+#define EGL_KHR_reusable_sync 1
+
+typedef void* EGLSyncKHR;
+typedef khronos_utime_nanoseconds_t EGLTimeKHR;
+
+#define EGL_SYNC_STATUS_KHR			0x30F1
+#define EGL_SIGNALED_KHR			0x30F2
+#define EGL_UNSIGNALED_KHR			0x30F3
+#define EGL_TIMEOUT_EXPIRED_KHR			0x30F5
+#define EGL_CONDITION_SATISFIED_KHR		0x30F6
+#define EGL_SYNC_TYPE_KHR			0x30F7
+#define EGL_SYNC_REUSABLE_KHR			0x30FA
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_KHR		0x0001	/* eglClientWaitSyncKHR <flags> bitfield */
+#define EGL_FOREVER_KHR				0xFFFFFFFFFFFFFFFFull
+#define EGL_NO_SYNC_KHR				((EGLSyncKHR)0)
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLAPI EGLSyncKHR EGLAPIENTRY eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+EGLAPI EGLBoolean EGLAPIENTRY eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync);
+EGLAPI EGLint EGLAPIENTRY eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+EGLAPI EGLBoolean EGLAPIENTRY eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+EGLAPI EGLBoolean EGLAPIENTRY eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSyncKHR (EGLAPIENTRYP PFNEGLCREATESYNCKHRPROC) (EGLDisplay dpy, EGLenum type, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBKHRPROC) (EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value);
+#endif
+
 #ifndef EGL_KHR_image_base
 #define EGL_KHR_image_base 1
 /* Most interfaces defined by EGL_KHR_image_pixmap above */
@@ -131,6 +161,67 @@
 /* Interfaces defined by EGL_KHR_image above */
 #endif
 
+#ifndef EGL_IMG_context_priority
+#define EGL_IMG_context_priority 1
+#define EGL_CONTEXT_PRIORITY_LEVEL_IMG		0x3100
+#define EGL_CONTEXT_PRIORITY_HIGH_IMG		0x3101
+#define EGL_CONTEXT_PRIORITY_MEDIUM_IMG		0x3102
+#define EGL_CONTEXT_PRIORITY_LOW_IMG		0x3103
+#endif
+
+#ifndef EGL_NV_coverage_sample
+#define EGL_NV_coverage_sample 1
+#define EGL_COVERAGE_BUFFERS_NV 0x30E0
+#define EGL_COVERAGE_SAMPLES_NV 0x30E1
+#endif
+
+#ifndef EGL_NV_depth_nonlinear
+#define EGL_NV_depth_nonlinear 1
+#define EGL_DEPTH_ENCODING_NV 0x30E2
+#define EGL_DEPTH_ENCODING_NONE_NV 0
+#define EGL_DEPTH_ENCODING_NONLINEAR_NV 0x30E3
+#endif
+
+#ifndef EGL_NV_sync
+#define EGL_NV_sync 1
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_NV	0x30E6
+#define EGL_SYNC_STATUS_NV			0x30E7
+#define EGL_SIGNALED_NV				0x30E8
+#define EGL_UNSIGNALED_NV			0x30E9
+#define EGL_SYNC_FLUSH_COMMANDS_BIT_NV		0x0001
+#define EGL_FOREVER_NV				0xFFFFFFFFFFFFFFFFull
+#define EGL_ALREADY_SIGNALED_NV			0x30EA
+#define EGL_TIMEOUT_EXPIRED_NV			0x30EB
+#define EGL_CONDITION_SATISFIED_NV		0x30EC
+#define EGL_SYNC_TYPE_NV			0x30ED
+#define EGL_SYNC_CONDITION_NV			0x30EE
+#define EGL_SYNC_FENCE_NV			0x30EF
+#define EGL_NO_SYNC_NV				((EGLSyncNV)0)
+typedef void* EGLSyncNV;
+typedef unsigned long long EGLTimeNV;
+#ifdef EGL_EGLEXT_PROTOTYPES
+EGLSyncNV eglCreateFenceSyncNV (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+EGLBoolean eglDestroySyncNV (EGLSyncNV sync);
+EGLBoolean eglFenceNV (EGLSyncNV sync);
+EGLint eglClientWaitSyncNV (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+EGLBoolean eglSignalSyncNV (EGLSyncNV sync, EGLenum mode);
+EGLBoolean eglGetSyncAttribNV (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif /* EGL_EGLEXT_PROTOTYPES */
+typedef EGLSyncNV (EGLAPIENTRYP PFNEGLCREATEFENCESYNCNVPROC) (EGLDisplay dpy, EGLenum condition, const EGLint *attrib_list);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSYNCNVPROC) (EGLSyncNV sync);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLFENCENVPROC) (EGLSyncNV sync);
+typedef EGLint (EGLAPIENTRYP PFNEGLCLIENTWAITSYNCNVPROC) (EGLSyncNV sync, EGLint flags, EGLTimeNV timeout);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLSIGNALSYNCNVPROC) (EGLSyncNV sync, EGLenum mode);
+typedef EGLBoolean (EGLAPIENTRYP PFNEGLGETSYNCATTRIBNVPROC) (EGLSyncNV sync, EGLint attribute, EGLint *value);
+#endif
+
+#ifndef EGL_KHR_fence_sync
+#define EGL_KHR_fence_sync 1
+/* Reuses most tokens and entry points from EGL_KHR_reusable_sync */
+#define EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR	0x30F0
+#define EGL_SYNC_CONDITION_KHR			0x30F8
+#define EGL_SYNC_FENCE_KHR			0x30F9
+#endif
 
 #ifndef EGL_ANDROID_image_native_buffer
 #define EGL_ANDROID_image_native_buffer 1
@@ -138,14 +229,6 @@
 #define EGL_NATIVE_BUFFER_ANDROID       0x3140  /* eglCreateImageKHR target */
 #endif
 
-#ifndef EGL_ANDROID_get_render_buffer
-#define EGL_ANDROID_get_render_buffer 1
-#ifdef EGL_EGLEXT_PROTOTYPES
-EGLAPI EGLClientBuffer EGLAPIENTRY eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw);
-#endif
-typedef EGLClientBuffer (EGLAPIENTRYP PFNEGLGETRENDERBUFFERANDROIDPROC) (EGLDisplay dpy, EGLSurface draw);
-#endif
-
 #ifndef EGL_ANDROID_swap_rectangle
 #define EGL_ANDROID_swap_rectangle 1
 #ifdef EGL_EGLEXT_PROTOTYPES
@@ -154,7 +237,6 @@
 typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSWAPRECTANGLEANDROIDPROC) (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height);
 #endif
 
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/opengl/include/EGL/eglplatform.h b/opengl/include/EGL/eglplatform.h
index 53e9e61..25d7697 100644
--- a/opengl/include/EGL/eglplatform.h
+++ b/opengl/include/EGL/eglplatform.h
@@ -25,7 +25,7 @@
 */
 
 /* Platform-specific types and definitions for egl.h
- * $Revision: 7244 $ on $Date: 2009-01-20 17:06:59 -0800 (Tue, 20 Jan 2009) $
+ * $Revision: 9724 $ on $Date: 2009-12-02 02:05:33 -0800 (Wed, 02 Dec 2009) $
  *
  * Adopters may modify khrplatform.h and this file to suit their platform.
  * You are encouraged to submit all modifications to the Khronos group so that
@@ -50,8 +50,10 @@
 #define EGLAPI KHRONOS_APICALL
 #endif
 
+#ifndef EGLAPIENTRY
 #define EGLAPIENTRY  KHRONOS_APIENTRY
-#define EGLAPIENTRYP KHRONOS_APIENTRY*
+#endif
+#define EGLAPIENTRYP EGLAPIENTRY*
 
 /* The types NativeDisplayType, NativeWindowType, and NativePixmapType
  * are aliases of window-system-dependent types, such as X Display * or
@@ -89,10 +91,11 @@
 
 #elif defined(ANDROID)
 
-struct android_native_window_t;
+#include <android/native_window.h>
+
 struct egl_native_pixmap_t;
 
-typedef struct android_native_window_t* EGLNativeWindowType;
+typedef struct ANativeWindow*           EGLNativeWindowType;
 typedef struct egl_native_pixmap_t*     EGLNativePixmapType;
 typedef void*                           EGLNativeDisplayType;
 
diff --git a/opengl/include/GLES/gl.h b/opengl/include/GLES/gl.h
index 2e8b971..5b8d85a 100644
--- a/opengl/include/GLES/gl.h
+++ b/opengl/include/GLES/gl.h
@@ -1,7 +1,7 @@
 #ifndef __gl_h_
 #define __gl_h_
 
-/* $Revision: 7172 $ on $Date:: 2009-01-09 11:17:41 -0800 #$ */
+/* $Revision: 10601 $ on $Date:: 2010-03-04 22:15:27 -0800 #$ */
 
 #include <GLES/glplatform.h>
 
@@ -15,6 +15,7 @@
  */
 
 typedef void             GLvoid;
+typedef char             GLchar;
 typedef unsigned int     GLenum;
 typedef unsigned char    GLboolean;
 typedef unsigned int     GLbitfield;
@@ -678,7 +679,7 @@
 GL_API void GL_APIENTRY glGetIntegerv (GLenum pname, GLint *params);
 GL_API void GL_APIENTRY glGetLightxv (GLenum light, GLenum pname, GLfixed *params);
 GL_API void GL_APIENTRY glGetMaterialxv (GLenum face, GLenum pname, GLfixed *params);
-GL_API void GL_APIENTRY glGetPointerv (GLenum pname, void **params);
+GL_API void GL_APIENTRY glGetPointerv (GLenum pname, GLvoid **params);
 GL_API const GLubyte * GL_APIENTRY glGetString (GLenum name);
 GL_API void GL_APIENTRY glGetTexEnviv (GLenum env, GLenum pname, GLint *params);
 GL_API void GL_APIENTRY glGetTexEnvxv (GLenum env, GLenum pname, GLfixed *params);
diff --git a/opengl/include/GLES/glext.h b/opengl/include/GLES/glext.h
index a8fe2e9..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..163b2db 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -158,7 +158,6 @@
     virtual     EGLint      getSwapBehavior() const;
     virtual     EGLBoolean  swapBuffers();
     virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
-    virtual     EGLClientBuffer getRenderBuffer() const;
 protected:
     GGLSurface              depth;
 };
@@ -202,9 +201,6 @@
 {
     return EGL_FALSE;
 }
-EGLClientBuffer egl_surface_t::getRenderBuffer() const {
-    return 0;
-}
 
 // ----------------------------------------------------------------------------
 
@@ -213,7 +209,7 @@
     egl_window_surface_v2_t(
             EGLDisplay dpy, EGLConfig config,
             int32_t depthFormat,
-            android_native_window_t* window);
+            ANativeWindow* window);
 
     ~egl_window_surface_v2_t();
 
@@ -230,12 +226,11 @@
     virtual     EGLint      getRefreshRate() const;
     virtual     EGLint      getSwapBehavior() const;
     virtual     EGLBoolean  setSwapRectangle(EGLint l, EGLint t, EGLint w, EGLint h);
-    virtual     EGLClientBuffer  getRenderBuffer() const;
     
 private:
     status_t lock(android_native_buffer_t* buf, int usage, void** vaddr);
     status_t unlock(android_native_buffer_t* buf);
-    android_native_window_t*   nativeWindow;
+    ANativeWindow*   nativeWindow;
     android_native_buffer_t*   buffer;
     android_native_buffer_t*   previousBuffer;
     gralloc_module_t const*    module;
@@ -355,7 +350,7 @@
 egl_window_surface_v2_t::egl_window_surface_v2_t(EGLDisplay dpy,
         EGLConfig config,
         int32_t depthFormat,
-        android_native_window_t* window)
+        ANativeWindow* window)
     : egl_surface_t(dpy, config, depthFormat), 
     nativeWindow(window), buffer(0), previousBuffer(0), module(0),
     blitengine(0), bits(NULL)
@@ -576,41 +571,44 @@
     buffer = 0;
 
     // dequeue a new buffer
-    nativeWindow->dequeueBuffer(nativeWindow, &buffer);
-    
-    // TODO: lockBuffer should rather be executed when the very first
-    // direct rendering occurs.
-    nativeWindow->lockBuffer(nativeWindow, buffer);
-    
-    // reallocate the depth-buffer if needed
-    if ((width != buffer->width) || (height != buffer->height)) {
-        // TODO: we probably should reset the swap rect here
-        // if the window size has changed
-        width = buffer->width;
-        height = buffer->height;
-        if (depth.data) {
-            free(depth.data);
-            depth.width   = width;
-            depth.height  = height;
-            depth.stride  = buffer->stride;
-            depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
-            if (depth.data == 0) {
-                setError(EGL_BAD_ALLOC, EGL_FALSE);
-                return EGL_FALSE;
+    if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) == NO_ERROR) {
+
+        // TODO: lockBuffer should rather be executed when the very first
+        // direct rendering occurs.
+        nativeWindow->lockBuffer(nativeWindow, buffer);
+
+        // reallocate the depth-buffer if needed
+        if ((width != buffer->width) || (height != buffer->height)) {
+            // TODO: we probably should reset the swap rect here
+            // if the window size has changed
+            width = buffer->width;
+            height = buffer->height;
+            if (depth.data) {
+                free(depth.data);
+                depth.width   = width;
+                depth.height  = height;
+                depth.stride  = buffer->stride;
+                depth.data    = (GGLubyte*)malloc(depth.stride*depth.height*2);
+                if (depth.data == 0) {
+                    setError(EGL_BAD_ALLOC, EGL_FALSE);
+                    return EGL_FALSE;
+                }
             }
         }
-    }
-    
-    // keep a reference on the buffer
-    buffer->common.incRef(&buffer->common);
 
-    // finally pin the buffer down
-    if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN | 
-            GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
-        LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
-                buffer, buffer->width, buffer->height);
-        return setError(EGL_BAD_ACCESS, EGL_FALSE);
-        // FIXME: we should make sure we're not accessing the buffer anymore
+        // keep a reference on the buffer
+        buffer->common.incRef(&buffer->common);
+
+        // finally pin the buffer down
+        if (lock(buffer, GRALLOC_USAGE_SW_READ_OFTEN |
+                GRALLOC_USAGE_SW_WRITE_OFTEN, &bits) != NO_ERROR) {
+            LOGE("eglSwapBuffers() failed to lock buffer %p (%ux%u)",
+                    buffer, buffer->width, buffer->height);
+            return setError(EGL_BAD_ACCESS, EGL_FALSE);
+            // FIXME: we should make sure we're not accessing the buffer anymore
+        }
+    } else {
+        return setError(EGL_BAD_CURRENT_SURFACE, EGL_FALSE);
     }
 
     return EGL_TRUE;
@@ -623,28 +621,6 @@
     return EGL_TRUE;
 }
 
-EGLClientBuffer egl_window_surface_v2_t::getRenderBuffer() const
-{
-    return buffer;
-}
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-
-static bool supportedCopybitsDestinationFormat(int format) {
-    // Hardware supported
-    switch (format) {
-    case HAL_PIXEL_FORMAT_RGB_565:
-    case HAL_PIXEL_FORMAT_RGBA_8888:
-    case HAL_PIXEL_FORMAT_RGBX_8888:
-    case HAL_PIXEL_FORMAT_RGBA_4444:
-    case HAL_PIXEL_FORMAT_RGBA_5551:
-    case HAL_PIXEL_FORMAT_BGRA_8888:
-        return true;
-    }
-    return false;
-}
-#endif
-
 EGLBoolean egl_window_surface_v2_t::bindDrawSurface(ogles_context_t* gl)
 {
     GGLSurface buffer;
@@ -658,18 +634,6 @@
     if (depth.data != gl->rasterizer.state.buffers.depth.data)
         gl->rasterizer.procs.depthBuffer(gl, &depth);
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    gl->copybits.drawSurfaceBuffer = 0;
-    if (gl->copybits.blitEngine != NULL) {
-        if (supportedCopybitsDestinationFormat(buffer.format)) {
-            buffer_handle_t handle = this->buffer->handle;
-            if (handle != NULL) {
-                gl->copybits.drawSurfaceBuffer = this->buffer;
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return EGL_TRUE;
 }
 EGLBoolean egl_window_surface_v2_t::bindReadSurface(ogles_context_t* gl)
@@ -883,7 +847,6 @@
         // "KHR_image_pixmap "
         "EGL_ANDROID_image_native_buffer "
         "EGL_ANDROID_swap_rectangle "
-        "EGL_ANDROID_get_render_buffer "
         ;
 
 // ----------------------------------------------------------------------------
@@ -936,8 +899,6 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "eglGetRenderBufferANDROID", 
-            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
 /*
@@ -1300,7 +1261,7 @@
     if (!(surfaceType & EGL_WINDOW_BIT))
         return setError(EGL_BAD_MATCH, EGL_NO_SURFACE);
 
-    if (static_cast<android_native_window_t*>(window)->common.magic !=
+    if (static_cast<ANativeWindow*>(window)->common.magic !=
             ANDROID_NATIVE_WINDOW_MAGIC) {
         return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE);
     }
@@ -1323,7 +1284,7 @@
 
     egl_surface_t* surface;
     surface = new egl_window_surface_v2_t(dpy, config, depthFormat,
-            static_cast<android_native_window_t*>(window));
+            static_cast<ANativeWindow*>(window));
 
     if (!surface->initCheck()) {
         // there was a problem in the ctor, the error
@@ -1525,8 +1486,13 @@
     }
 
     if (ggl_unlikely(attrib_list==0)) {
-        *num_config = 0;
-        return EGL_TRUE;
+        /*
+         * A NULL attrib_list should be treated as though it was an empty
+         * one (terminated with EGL_NONE) as defined in
+         * section 3.4.1 "Querying Configurations" in the EGL specification.
+         */
+        static const EGLint dummy = EGL_NONE;
+        attrib_list = &dummy;
     }
 
     int numAttributes = 0;
@@ -2150,18 +2116,3 @@
 
     return EGL_TRUE;
 }
-
-EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw)
-{
-    if (egl_display_t::is_valid(dpy) == EGL_FALSE)
-        return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0);
-
-    egl_surface_t* d = static_cast<egl_surface_t*>(draw);
-    if (!d->isValid())
-        return setError(EGL_BAD_SURFACE, (EGLClientBuffer)0);
-    if (d->dpy != dpy)
-        return setError(EGL_BAD_DISPLAY, (EGLClientBuffer)0);
-
-    // post the surface
-    return d->getRenderBuffer();
-}
diff --git a/opengl/libagl/state.cpp b/opengl/libagl/state.cpp
index 27bb545..a0f720a 100644
--- a/opengl/libagl/state.cpp
+++ b/opengl/libagl/state.cpp
@@ -28,10 +28,6 @@
 #include "BufferObjectManager.h"
 #include "TextureObjectManager.h"
 
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-#include <hardware/copybit.h>
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
 namespace android {
 
 // ----------------------------------------------------------------------------
@@ -101,35 +97,6 @@
     // OpenGL enables dithering by default
     c->rasterizer.procs.enable(c, GL_DITHER);
 
-    c->copybits.blitEngine = NULL;
-    c->copybits.minScale = 0;
-    c->copybits.maxScale = 0;
-    c->copybits.drawSurfaceBuffer = 0;
-
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    hw_module_t const* module;
-    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
-        struct copybit_device_t* copyBits;
-        if (copybit_open(module, &copyBits) == 0) {
-            c->copybits.blitEngine = copyBits;
-            {
-                int minLim = copyBits->get(copyBits,
-                        COPYBIT_MINIFICATION_LIMIT);
-                if (minLim != -EINVAL && minLim > 0) {
-                    c->copybits.minScale = (1 << 16) / minLim;
-                }
-            }
-            {
-                int magLim = copyBits->get(copyBits,
-                        COPYBIT_MAGNIFICATION_LIMIT);
-                if (magLim != -EINVAL && magLim > 0) {
-                    c->copybits.maxScale = min(32*1024-1, magLim) << 16;
-                }
-            }
-        }
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
-
     return c;
 }
 
@@ -144,11 +111,6 @@
     c->bufferObjectManager->decStrong(c);
     ggl_uninit_context(&(c->rasterizer));
     free(c->rasterizer.base);
-#ifdef LIBAGL_USE_GRALLOC_COPYBITS
-    if (c->copybits.blitEngine != NULL) {
-        copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
-    }
-#endif // LIBAGL_USE_GRALLOC_COPYBITS
 }
 
 void _ogles_error(ogles_context_t* c, GLenum error)
diff --git a/opengl/libagl/texture.cpp b/opengl/libagl/texture.cpp
index 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..105ebb4 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -37,12 +37,13 @@
 #include <cutils/memory.h>
 
 #include <utils/SortedVector.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
 
 #include "hooks.h"
 #include "egl_impl.h"
 #include "Loader.h"
 
-#define MAKE_CONFIG(_impl, _index)  ((EGLConfig)(((_impl)<<24) | (_index)))
 #define setError(_e, _r) setErrorEtc(__FUNCTION__, __LINE__, _e, _r)
 
 // ----------------------------------------------------------------------------
@@ -60,7 +61,6 @@
         "EGL_KHR_image_pixmap "
         "EGL_ANDROID_image_native_buffer "
         "EGL_ANDROID_swap_rectangle "
-        "EGL_ANDROID_get_render_buffer "
         ;
 
 // ----------------------------------------------------------------------------
@@ -143,6 +143,22 @@
 SortedVector<egl_object_t*> egl_object_t::sObjects;
 Mutex egl_object_t::sLock;
 
+
+struct egl_config_t {
+    egl_config_t() {}
+    egl_config_t(int impl, EGLConfig config)
+        : impl(impl), config(config), configId(0), implConfigId(0) { }
+    int         impl;           // the implementation this config is for
+    EGLConfig   config;         // the implementation's EGLConfig
+    EGLint      configId;       // our CONFIG_ID
+    EGLint      implConfigId;   // the implementation's CONFIG_ID
+    inline bool operator < (const egl_config_t& rhs) const {
+        if (impl < rhs.impl) return true;
+        if (impl > rhs.impl) return false;
+        return config < rhs.config;
+    }
+};
+
 struct egl_display_t {
     enum { NOT_INITIALIZED, INITIALIZED, TERMINATED };
     
@@ -163,13 +179,14 @@
         strings_t   queryString;
     };
 
-    uint32_t    magic;
-    DisplayImpl disp[IMPL_NUM_IMPLEMENTATIONS];
-    EGLint      numTotalConfigs;
-    uint32_t    refs;
-    Mutex       lock;
+    uint32_t        magic;
+    DisplayImpl     disp[IMPL_NUM_IMPLEMENTATIONS];
+    EGLint          numTotalConfigs;
+    egl_config_t*   configs;
+    uint32_t        refs;
+    Mutex           lock;
     
-    egl_display_t() : magic('_dpy'), numTotalConfigs(0) { }
+    egl_display_t() : magic('_dpy'), numTotalConfigs(0), configs(0) { }
     ~egl_display_t() { magic = 0; }
     inline bool isValid() const { return magic == '_dpy'; }
     inline bool isAlive() const { return isValid(); }
@@ -179,14 +196,15 @@
 {
     typedef egl_object_t::LocalRef<egl_surface_t, EGLSurface> Ref;
 
-    egl_surface_t(EGLDisplay dpy, EGLSurface surface,
+    egl_surface_t(EGLDisplay dpy, EGLSurface surface, EGLConfig config,
             int impl, egl_connection_t const* cnx) 
-    : dpy(dpy), surface(surface), impl(impl), cnx(cnx) {
+    : dpy(dpy), surface(surface), config(config), impl(impl), cnx(cnx) {
     }
     ~egl_surface_t() {
     }
     EGLDisplay                  dpy;
     EGLSurface                  surface;
+    EGLConfig                   config;
     int                         impl;
     egl_connection_t const*     cnx;
 };
@@ -195,7 +213,7 @@
 {
     typedef egl_object_t::LocalRef<egl_context_t, EGLContext> Ref;
     
-    egl_context_t(EGLDisplay dpy, EGLContext context,
+    egl_context_t(EGLDisplay dpy, EGLContext context, EGLConfig config,
             int impl, egl_connection_t const* cnx, int version) 
     : dpy(dpy), context(context), read(0), draw(0), impl(impl), cnx(cnx),
       version(version)
@@ -203,6 +221,7 @@
     }
     EGLDisplay                  dpy;
     EGLContext                  context;
+    EGLConfig                   config;
     EGLSurface                  read;
     EGLSurface                  draw;
     int                         impl;
@@ -220,7 +239,7 @@
         memset(images, 0, sizeof(images));
     }
     EGLDisplay dpy;
-    EGLConfig context;
+    EGLContext context;
     EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS];
 };
 
@@ -239,7 +258,7 @@
 
 // ----------------------------------------------------------------------------
 
-egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
+static egl_connection_t gEGLImpl[IMPL_NUM_IMPLEMENTATIONS];
 static egl_display_t gDisplay[NUM_DISPLAYS];
 static pthread_mutex_t gThreadLocalStorageKeyMutex = PTHREAD_MUTEX_INITIALIZER;
 static pthread_key_t gEGLThreadLocalStorageKey = -1;
@@ -354,7 +373,7 @@
 {
     while (first <= last) {
         int mid = (first + last) / 2;
-        if (key > sortedArray[mid]) { 
+        if (sortedArray[mid] < key) {
             first = mid + 1;
         } else if (key < sortedArray[mid]) { 
             last = mid - 1;
@@ -365,26 +384,11 @@
     return -1;
 }
 
-static EGLint configToUniqueId(egl_display_t const* dp, int i, int index) 
-{
-    // NOTE: this mapping works only if we have no more than two EGLimpl
-    return (i>0 ? dp->disp[0].numConfigs : 0) + index;
-}
-
-static void uniqueIdToConfig(egl_display_t const* dp, EGLint configId,
-        int& i, int& index) 
-{
-    // NOTE: this mapping works only if we have no more than two EGLimpl
-    size_t numConfigs = dp->disp[0].numConfigs;
-    i = configId / numConfigs;
-    index = configId % numConfigs;
-}
-
 static int cmp_configs(const void* a, const void *b)
 {
-    EGLConfig c0 = *(EGLConfig const *)a;
-    EGLConfig c1 = *(EGLConfig const *)b;
-    return c0<c1 ? -1 : (c0>c1 ? 1 : 0);
+    const egl_config_t& c0 = *(egl_config_t const *)a;
+    const egl_config_t& c1 = *(egl_config_t const *)b;
+    return c0<c1 ? -1 : (c1<c0 ? 1 : 0);
 }
 
 struct extention_map_t {
@@ -403,11 +407,13 @@
             (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, 
     { "eglSetSwapRectangleANDROID", 
             (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, 
-    { "eglGetRenderBufferANDROID", 
-            (__eglMustCastToProperFunctionPointerType)&eglGetRenderBufferANDROID }, 
 };
 
-static extention_map_t gGLExtentionMap[MAX_NUMBER_OF_GL_EXTENSIONS];
+extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS];
+
+// accesses protected by gInitDriverMutex
+static DefaultKeyedVector<String8, __eglMustCastToProperFunctionPointerType> gGLExtentionMap;
+static int gGLExtentionSlot = 0;
 
 static void(*findProcAddress(const char* name,
         const extention_map_t* map, size_t n))() 
@@ -477,20 +483,15 @@
 
 static egl_connection_t* validate_display_config(
         EGLDisplay dpy, EGLConfig config,
-        egl_display_t const*& dp, int& impl, int& index)
+        egl_display_t const*& dp)
 {
     dp = get_display(dpy);
     if (!dp) return setError(EGL_BAD_DISPLAY, (egl_connection_t*)NULL);
 
-    impl = uintptr_t(config)>>24;
-    if (uint32_t(impl) >= IMPL_NUM_IMPLEMENTATIONS) {
-        return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
-    } 
-    index = uintptr_t(config) & 0xFFFFFF;
-    if (index >= dp->disp[impl].numConfigs) {
+    if (intptr_t(config) >= dp->numTotalConfigs) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
     }
-    egl_connection_t* const cnx = &gEGLImpl[impl];
+    egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(config)].impl];
     if (cnx->dso == 0) {
         return setError(EGL_BAD_CONFIG, (egl_connection_t*)NULL);
     }
@@ -718,11 +719,6 @@
                             dp->disp[i].dpy, dp->disp[i].config, n,
                             &dp->disp[i].numConfigs))
                     {
-                        // sort the configurations so we can do binary searches
-                        qsort(  dp->disp[i].config,
-                                dp->disp[i].numConfigs,
-                                sizeof(EGLConfig), cmp_configs);
-
                         dp->numTotalConfigs += n;
                         res = EGL_TRUE;
                     }
@@ -732,6 +728,30 @@
     }
 
     if (res == EGL_TRUE) {
+        dp->configs = new egl_config_t[ dp->numTotalConfigs ];
+        for (int i=0, k=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
+            egl_connection_t* const cnx = &gEGLImpl[i];
+            if (cnx->dso && cnx->major>=0 && cnx->minor>=0) {
+                for (int j=0 ; j<dp->disp[i].numConfigs ; j++) {
+                    dp->configs[k].impl = i;
+                    dp->configs[k].config = dp->disp[i].config[j];
+                    dp->configs[k].configId = k + 1; // CONFIG_ID start at 1
+                    // store the implementation's CONFIG_ID
+                    cnx->egl.eglGetConfigAttrib(
+                            dp->disp[i].dpy,
+                            dp->disp[i].config[j],
+                            EGL_CONFIG_ID,
+                            &dp->configs[k].implConfigId);
+                    k++;
+                }
+            }
+        }
+
+        // sort our configurations so we can do binary-searches
+        qsort(  dp->configs,
+                dp->numTotalConfigs,
+                sizeof(egl_config_t), cmp_configs);
+
         dp->refs++;
         if (major != NULL) *major = VERSION_MAJOR;
         if (minor != NULL) *minor = VERSION_MINOR;
@@ -784,6 +804,7 @@
     
     dp->refs--;
     dp->numTotalConfigs = 0;
+    delete [] dp->configs;
     clearTLS();
     return res;
 }
@@ -804,14 +825,13 @@
         *num_config = numConfigs;
         return EGL_TRUE;
     }
+
     GLint n = 0;
-    for (int j=0 ; j<IMPL_NUM_IMPLEMENTATIONS ; j++) {
-        for (int i=0 ; i<dp->disp[j].numConfigs && config_size ; i++) {
-            *configs++ = MAKE_CONFIG(j, i);
-            config_size--;
-            n++;
-        }
-    }    
+    for (intptr_t i=0 ; i<dp->numTotalConfigs && config_size ; i++) {
+        *configs++ = EGLConfig(i);
+        config_size--;
+        n++;
+    }
     
     *num_config = n;
     return EGL_TRUE;
@@ -834,7 +854,7 @@
 
     
     // It is unfortunate, but we need to remap the EGL_CONFIG_IDs, 
-    // to do  this, we have to go through the attrib_list array once
+    // to do this, we have to go through the attrib_list array once
     // to figure out both its size and if it contains an EGL_CONFIG_ID
     // key. If so, the full array is copied and patched.
     // NOTE: we assume that there can be only one occurrence
@@ -843,10 +863,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 +878,20 @@
         memcpy(new_list, attrib_list, size*sizeof(EGLint));
 
         // patch the requested EGL_CONFIG_ID
-        int i, index;
+        bool found = false;
+        EGLConfig ourConfig(0);
         EGLint& configId(new_list[patch_index+1]);
-        uniqueIdToConfig(dp, configId, i, index);
-        
-        egl_connection_t* const cnx = &gEGLImpl[i];
-        if (cnx->dso) {
-            cnx->egl.eglGetConfigAttrib(
-                    dp->disp[i].dpy, dp->disp[i].config[index], 
-                    EGL_CONFIG_ID, &configId);
+        for (intptr_t i=0 ; i<dp->numTotalConfigs ; i++) {
+            if (dp->configs[i].configId == configId) {
+                ourConfig = EGLConfig(i);
+                configId = dp->configs[i].implConfigId;
+                found = true;
+                break;
+            }
+        }
 
+        egl_connection_t* const cnx = &gEGLImpl[dp->configs[intptr_t(ourConfig)].impl];
+        if (found && cnx->dso) {
             // and switch to the new list
             attrib_list = const_cast<const EGLint *>(new_list);
 
@@ -878,12 +904,13 @@
             // which one.
 
             res = cnx->egl.eglChooseConfig(
-                    dp->disp[i].dpy, attrib_list, configs, config_size, &n);
+                    dp->disp[ dp->configs[intptr_t(ourConfig)].impl ].dpy,
+                    attrib_list, configs, config_size, &n);
             if (res && n>0) {
                 // n has to be 0 or 1, by construction, and we already know
                 // which config it will return (since there can be only one).
                 if (configs) {
-                    configs[0] = MAKE_CONFIG(i, index);
+                    configs[0] = ourConfig;
                 }
                 *num_config = 1;
             }
@@ -893,6 +920,7 @@
         return res;
     }
 
+
     for (int i=0 ; i<IMPL_NUM_IMPLEMENTATIONS ; i++) {
         egl_connection_t* const cnx = &gEGLImpl[i];
         if (cnx->dso) {
@@ -900,15 +928,14 @@
                     dp->disp[i].dpy, attrib_list, configs, config_size, &n)) {
                 if (configs) {
                     // now we need to convert these client EGLConfig to our
-                    // internal EGLConfig format. This is done in O(n log n).
+                    // internal EGLConfig format.
+                    // This is done in O(n Log(n)) time.
                     for (int j=0 ; j<n ; j++) {
-                        int index = binarySearch<EGLConfig>(
-                                dp->disp[i].config, 0,
-                                dp->disp[i].numConfigs-1, configs[j]);
+                        egl_config_t key(i, configs[j]);
+                        intptr_t index = binarySearch<egl_config_t>(
+                                dp->configs, 0, dp->numTotalConfigs, key);
                         if (index >= 0) {
-                            if (configs) {
-                                configs[j] = MAKE_CONFIG(i, index);
-                            }
+                            configs[j] = EGLConfig(index);
                         } else {
                             return setError(EGL_BAD_CONFIG, EGL_FALSE);
                         }
@@ -928,18 +955,16 @@
         EGLint attribute, EGLint *value)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (!cnx) return EGL_FALSE;
     
     if (attribute == EGL_CONFIG_ID) {
-        // EGL_CONFIG_IDs must be unique, just use the order of the selected
-        // EGLConfig.
-        *value = configToUniqueId(dp, i, index);
+        *value = dp->configs[intptr_t(config)].configId;
         return EGL_TRUE;
     }
     return cnx->egl.eglGetConfigAttrib(
-            dp->disp[i].dpy, dp->disp[i].config[index], attribute, value);
+            dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+            dp->configs[intptr_t(config)].config, attribute, value);
 }
 
 // ----------------------------------------------------------------------------
@@ -951,13 +976,14 @@
                                     const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreateWindowSurface(
-                dp->disp[i].dpy, dp->disp[i].config[index], window, attrib_list);       
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config, window, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+                    dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
     }
@@ -969,13 +995,14 @@
                                     const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreatePixmapSurface(
-                dp->disp[i].dpy, dp->disp[i].config[index], pixmap, attrib_list);
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config, pixmap, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+                    dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
     }
@@ -986,13 +1013,14 @@
                                     const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
         EGLSurface surface = cnx->egl.eglCreatePbufferSurface(
-                dp->disp[i].dpy, dp->disp[i].config[index], attrib_list);
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config, attrib_list);
         if (surface != EGL_NO_SURFACE) {
-            egl_surface_t* s = new egl_surface_t(dpy, surface, i, cnx);
+            egl_surface_t* s = new egl_surface_t(dpy, surface, config,
+                    dp->configs[intptr_t(config)].impl, cnx);
             return s;
         }
     }
@@ -1028,23 +1056,35 @@
     egl_display_t const * const dp = get_display(dpy);
     egl_surface_t const * const s = get_surface(surface);
 
-    return s->cnx->egl.eglQuerySurface(
-            dp->disp[s->impl].dpy, s->surface, attribute, value);
+    EGLBoolean result(EGL_TRUE);
+    if (attribute == EGL_CONFIG_ID) {
+        // We need to remap EGL_CONFIG_IDs
+        *value = dp->configs[intptr_t(s->config)].configId;
+    } else {
+        result = s->cnx->egl.eglQuerySurface(
+                dp->disp[s->impl].dpy, s->surface, attribute, value);
+    }
+
+    return result;
 }
 
 // ----------------------------------------------------------------------------
-// contextes
+// Contexts
 // ----------------------------------------------------------------------------
 
 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config,
                             EGLContext share_list, const EGLint *attrib_list)
 {
     egl_display_t const* dp = 0;
-    int i=0, index=0;
-    egl_connection_t* cnx = validate_display_config(dpy, config, dp, i, index);
+    egl_connection_t* cnx = validate_display_config(dpy, config, dp);
     if (cnx) {
+        if (share_list != EGL_NO_CONTEXT) {
+            egl_context_t* const c = get_context(share_list);
+            share_list = c->context;
+        }
         EGLContext context = cnx->egl.eglCreateContext(
-                dp->disp[i].dpy, dp->disp[i].config[index],
+                dp->disp[ dp->configs[intptr_t(config)].impl ].dpy,
+                dp->configs[intptr_t(config)].config,
                 share_list, attrib_list);
         if (context != EGL_NO_CONTEXT) {
             // figure out if it's a GLESv1 or GLESv2
@@ -1062,7 +1102,8 @@
                     }
                 };
             }
-            egl_context_t* c = new egl_context_t(dpy, context, i, cnx, version);
+            egl_context_t* c = new egl_context_t(dpy, context, config,
+                    dp->configs[intptr_t(config)].impl, cnx, version);
             return c;
         }
     }
@@ -1207,8 +1248,16 @@
     egl_display_t const * const dp = get_display(dpy);
     egl_context_t * const c = get_context(ctx);
 
-    return c->cnx->egl.eglQueryContext(
-            dp->disp[c->impl].dpy, c->context, attribute, value);
+    EGLBoolean result(EGL_TRUE);
+    if (attribute == EGL_CONFIG_ID) {
+        *value = dp->configs[intptr_t(c->config)].configId;
+    } else {
+        // We need to remap EGL_CONFIG_IDs
+        result = c->cnx->egl.eglQueryContext(
+                dp->disp[c->impl].dpy, c->context, attribute, value);
+    }
+
+    return result;
 }
 
 EGLContext eglGetCurrentContext(void)
@@ -1295,16 +1344,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 +1374,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 +1631,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 +1771,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 +1809,3 @@
     }
     return setError(EGL_BAD_DISPLAY, NULL);
 }
-
-EGLClientBuffer eglGetRenderBufferANDROID(EGLDisplay dpy, EGLSurface draw)
-{
-    SurfaceRef _s(draw);
-    if (!_s.get()) return setError(EGL_BAD_SURFACE, (EGLClientBuffer*)0);
-
-    if (!validate_display_surface(dpy, draw))
-        return 0;    
-    egl_display_t const * const dp = get_display(dpy);
-    egl_surface_t const * const s = get_surface(draw);
-    if (s->cnx->egl.eglGetRenderBufferANDROID) {
-        return s->cnx->egl.eglGetRenderBufferANDROID(
-                dp->disp[s->impl].dpy, s->surface);
-    }
-    return setError(EGL_BAD_DISPLAY, (EGLClientBuffer*)0);
-}
diff --git a/opengl/libs/EGL/getProcAddress.cpp b/opengl/libs/EGL/getProcAddress.cpp
new file mode 100644
index 0000000..dcf8735
--- /dev/null
+++ b/opengl/libs/EGL/getProcAddress.cpp
@@ -0,0 +1,122 @@
+/*
+ ** Copyright 2009, The Android Open Source Project
+ **
+ ** Licensed under the Apache License, Version 2.0 (the "License");
+ ** you may not use this file except in compliance with the License.
+ ** You may obtain a copy of the License at
+ **
+ **     http://www.apache.org/licenses/LICENSE-2.0
+ **
+ ** Unless required by applicable law or agreed to in writing, software
+ ** distributed under the License is distributed on an "AS IS" BASIS,
+ ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ** See the License for the specific language governing permissions and
+ ** limitations under the License.
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <cutils/log.h>
+
+#include "hooks.h"
+
+// ----------------------------------------------------------------------------
+namespace android {
+// ----------------------------------------------------------------------------
+
+#undef API_ENTRY
+#undef CALL_GL_EXTENSION_API
+#undef GL_EXTENSION
+#undef GL_EXTENSION_NAME
+#undef GL_EXTENSION_ARRAY
+#undef GL_EXTENSION_LIST
+#undef GET_TLS
+
+#if defined(__arm__)
+
+    #ifdef HAVE_ARM_TLS_REGISTER
+        #define GET_TLS(reg) \
+            "mrc p15, 0, " #reg ", c13, c0, 3 \n"
+    #else
+        #define GET_TLS(reg) \
+            "mov   " #reg ", #0xFFFF0FFF      \n"  \
+            "ldr   " #reg ", [" #reg ", #-15] \n"
+    #endif
+
+    #define API_ENTRY(_api) __attribute__((naked)) _api
+
+    #define CALL_GL_EXTENSION_API(_api)                         \
+         asm volatile(                                          \
+            GET_TLS(r12)                                        \
+            "ldr   r12, [r12, %[tls]] \n"                       \
+            "cmp   r12, #0            \n"                       \
+            "ldrne r12, [r12, %[api]] \n"                       \
+            "cmpne r12, #0            \n"                       \
+            "bxne  r12                \n"                       \
+            "bx    lr                 \n"                       \
+            :                                                   \
+            : [tls] "J"(TLS_SLOT_OPENGL_API*4),                 \
+              [api] "J"(__builtin_offsetof(gl_hooks_t,          \
+                                      ext.extensions[_api]))    \
+            :                                                   \
+            );
+
+    #define GL_EXTENSION_NAME(_n)   __glExtFwd##_n
+
+    #define GL_EXTENSION(_n)                         \
+        void API_ENTRY(GL_EXTENSION_NAME(_n))() {    \
+            CALL_GL_EXTENSION_API(_n);               \
+        }
+
+
+#else
+
+    #define GL_EXTENSION_NAME(_n) NULL
+
+    #define GL_EXTENSION(_n)
+
+    #warning "eglGetProcAddress() partially supported on this architecture"
+
+#endif
+
+#define GL_EXTENSION_LIST(name) \
+        name(0)   name(1)   name(2)   name(3)   \
+        name(4)   name(5)   name(6)   name(7)   \
+        name(8)   name(9)   name(10)  name(11)  \
+        name(12)  name(13)  name(14)  name(15)  \
+        name(16)  name(17)  name(18)  name(19)  \
+        name(20)  name(21)  name(22)  name(23)  \
+        name(24)  name(25)  name(26)  name(27)  \
+        name(28)  name(29)  name(30)  name(31)  \
+        name(32)  name(33)  name(34)  name(35)  \
+        name(36)  name(37)  name(38)  name(39)  \
+        name(40)  name(41)  name(42)  name(43)  \
+        name(44)  name(45)  name(46)  name(47)  \
+        name(48)  name(49)  name(50)  name(51)  \
+        name(52)  name(53)  name(54)  name(55)  \
+        name(56)  name(57)  name(58)  name(59)  \
+        name(60)  name(61)  name(62)  name(63)
+
+
+GL_EXTENSION_LIST( GL_EXTENSION )
+
+#define GL_EXTENSION_ARRAY(_n)  GL_EXTENSION_NAME(_n),
+
+extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS] = {
+        GL_EXTENSION_LIST( GL_EXTENSION_ARRAY )
+ };
+
+#undef GET_TLS
+#undef GL_EXTENSION_LIST
+#undef GL_EXTENSION_ARRAY
+#undef GL_EXTENSION_NAME
+#undef GL_EXTENSION
+#undef API_ENTRY
+#undef CALL_GL_EXTENSION_API
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+// ----------------------------------------------------------------------------
+
diff --git a/opengl/libs/GLES2/gl2_api.in b/opengl/libs/GLES2/gl2_api.in
index 9c2e69a..5164450 100644
--- a/opengl/libs/GLES2/gl2_api.in
+++ b/opengl/libs/GLES2/gl2_api.in
@@ -4,7 +4,7 @@
 void API_ENTRY(glAttachShader)(GLuint program, GLuint shader) {
     CALL_GL_API(glAttachShader, program, shader);
 }
-void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const char* name) {
+void API_ENTRY(glBindAttribLocation)(GLuint program, GLuint index, const GLchar* name) {
     CALL_GL_API(glBindAttribLocation, program, index, name);
 }
 void API_ENTRY(glBindBuffer)(GLenum target, GLuint buffer) {
@@ -34,10 +34,10 @@
 void API_ENTRY(glBlendFuncSeparate)(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) {
     CALL_GL_API(glBlendFuncSeparate, srcRGB, dstRGB, srcAlpha, dstAlpha);
 }
-void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const void* data, GLenum usage) {
+void API_ENTRY(glBufferData)(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) {
     CALL_GL_API(glBufferData, target, size, data, usage);
 }
-void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) {
+void API_ENTRY(glBufferSubData)(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) {
     CALL_GL_API(glBufferSubData, target, offset, size, data);
 }
 GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target) {
@@ -61,10 +61,10 @@
 void API_ENTRY(glCompileShader)(GLuint shader) {
     CALL_GL_API(glCompileShader, shader);
 }
-void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
 }
-void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
 }
 void API_ENTRY(glCopyTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
@@ -121,7 +121,7 @@
 void API_ENTRY(glDrawArrays)(GLenum mode, GLint first, GLsizei count) {
     CALL_GL_API(glDrawArrays, mode, first, count);
 }
-void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const void* indices) {
+void API_ENTRY(glDrawElements)(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) {
     CALL_GL_API(glDrawElements, mode, count, type, indices);
 }
 void API_ENTRY(glEnable)(GLenum cap) {
@@ -160,16 +160,16 @@
 void API_ENTRY(glGenTextures)(GLsizei n, GLuint* textures) {
     CALL_GL_API(glGenTextures, n, textures);
 }
-void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) {
+void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
     CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
 }
-void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name) {
+void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) {
     CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
 }
 void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) {
     CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
 }
-int API_ENTRY(glGetAttribLocation)(GLuint program, const char* name) {
+int API_ENTRY(glGetAttribLocation)(GLuint program, const GLchar* name) {
     CALL_GL_API_RETURN(glGetAttribLocation, program, name);
 }
 void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params) {
@@ -193,7 +193,7 @@
 void API_ENTRY(glGetProgramiv)(GLuint program, GLenum pname, GLint* params) {
     CALL_GL_API(glGetProgramiv, program, pname, params);
 }
-void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, char* infolog) {
+void API_ENTRY(glGetProgramInfoLog)(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
     CALL_GL_API(glGetProgramInfoLog, program, bufsize, length, infolog);
 }
 void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params) {
@@ -202,13 +202,13 @@
 void API_ENTRY(glGetShaderiv)(GLuint shader, GLenum pname, GLint* params) {
     CALL_GL_API(glGetShaderiv, shader, pname, params);
 }
-void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog) {
+void API_ENTRY(glGetShaderInfoLog)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) {
     CALL_GL_API(glGetShaderInfoLog, shader, bufsize, length, infolog);
 }
 void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) {
     CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
 }
-void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, char* source) {
+void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) {
     CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
 }
 const GLubyte* API_ENTRY(glGetString)(GLenum name) {
@@ -226,7 +226,7 @@
 void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params) {
     CALL_GL_API(glGetUniformiv, program, location, params);
 }
-int API_ENTRY(glGetUniformLocation)(GLuint program, const char* name) {
+int API_ENTRY(glGetUniformLocation)(GLuint program, const GLchar* name) {
     CALL_GL_API_RETURN(glGetUniformLocation, program, name);
 }
 void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params) {
@@ -235,7 +235,7 @@
 void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params) {
     CALL_GL_API(glGetVertexAttribiv, index, pname, params);
 }
-void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, void** pointer) {
+void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer) {
     CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
 }
 void API_ENTRY(glHint)(GLenum target, GLenum mode) {
@@ -274,7 +274,7 @@
 void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units) {
     CALL_GL_API(glPolygonOffset, factor, units);
 }
-void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) {
+void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) {
     CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
 }
 void API_ENTRY(glReleaseShaderCompiler)(void) {
@@ -289,10 +289,10 @@
 void API_ENTRY(glScissor)(GLint x, GLint y, GLsizei width, GLsizei height) {
     CALL_GL_API(glScissor, x, y, width, height);
 }
-void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length) {
+void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) {
     CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
 }
-void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const char** string, const GLint* length) {
+void API_ENTRY(glShaderSource)(GLuint shader, GLsizei count, const GLchar** string, const GLint* length) {
     CALL_GL_API(glShaderSource, shader, count, string, length);
 }
 void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask) {
@@ -313,7 +313,7 @@
 void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) {
     CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
 }
-void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
+void API_ENTRY(glTexImage2D)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexImage2D, target, level, internalformat, width, height, border, format, type, pixels);
 }
 void API_ENTRY(glTexParameterf)(GLenum target, GLenum pname, GLfloat param) {
@@ -328,7 +328,7 @@
 void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params) {
     CALL_GL_API(glTexParameteriv, target, pname, params);
 }
-void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) {
+void API_ENTRY(glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexSubImage2D, target, level, xoffset, yoffset, width, height, format, type, pixels);
 }
 void API_ENTRY(glUniform1f)(GLint location, GLfloat x) {
@@ -418,7 +418,7 @@
 void API_ENTRY(glVertexAttrib4fv)(GLuint indx, const GLfloat* values) {
     CALL_GL_API(glVertexAttrib4fv, indx, values);
 }
-void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr) {
+void API_ENTRY(glVertexAttribPointer)(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) {
     CALL_GL_API(glVertexAttribPointer, indx, size, type, normalized, stride, ptr);
 }
 void API_ENTRY(glViewport)(GLint x, GLint y, GLsizei width, GLsizei height) {
diff --git a/opengl/libs/GLES2/gl2ext_api.in b/opengl/libs/GLES2/gl2ext_api.in
index 6eeecb3..e965625 100644
--- a/opengl/libs/GLES2/gl2ext_api.in
+++ b/opengl/libs/GLES2/gl2ext_api.in
@@ -4,10 +4,10 @@
 void API_ENTRY(__glEGLImageTargetRenderbufferStorageOES)(GLenum target, GLeglImageOES image) {
     CALL_GL_API(glEGLImageTargetRenderbufferStorageOES, target, image);
 }
-void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary) {
+void API_ENTRY(glGetProgramBinaryOES)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) {
     CALL_GL_API(glGetProgramBinaryOES, program, bufSize, length, binaryFormat, binary);
 }
-void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const void *binary, GLint length) {
+void API_ENTRY(glProgramBinaryOES)(GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length) {
     CALL_GL_API(glProgramBinaryOES, program, binaryFormat, binary, length);
 }
 void* API_ENTRY(glMapBufferOES)(GLenum target, GLenum access) {
@@ -16,40 +16,52 @@
 GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
     CALL_GL_API_RETURN(glUnmapBufferOES, target);
 }
-void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) {
+void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, GLvoid** params) {
     CALL_GL_API(glGetBufferPointervOES, target, pname, params);
 }
-void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) {
+void API_ENTRY(glTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexImage3DOES, target, level, internalformat, width, height, depth, border, format, type, pixels);
 }
-void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) {
+void API_ENTRY(glTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) {
     CALL_GL_API(glTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
 }
 void API_ENTRY(glCopyTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
     CALL_GL_API(glCopyTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, x, y, width, height);
 }
-void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexImage3DOES)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexImage3DOES, target, level, internalformat, width, height, depth, border, imageSize, data);
 }
-void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) {
+void API_ENTRY(glCompressedTexSubImage3DOES)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) {
     CALL_GL_API(glCompressedTexSubImage3DOES, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
 }
 void API_ENTRY(glFramebufferTexture3DOES)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) {
     CALL_GL_API(glFramebufferTexture3DOES, target, attachment, textarget, texture, level, zoffset);
 }
+void API_ENTRY(glBindVertexArrayOES)(GLuint array) {
+    CALL_GL_API(glBindVertexArrayOES, array);
+}
+void API_ENTRY(glDeleteVertexArraysOES)(GLsizei n, const GLuint *arrays) {
+    CALL_GL_API(glDeleteVertexArraysOES, n, arrays);
+}
+void API_ENTRY(glGenVertexArraysOES)(GLsizei n, GLuint *arrays) {
+    CALL_GL_API(glGenVertexArraysOES, n, arrays);
+}
+GLboolean API_ENTRY(glIsVertexArrayOES)(GLuint array) {
+    CALL_GL_API_RETURN(glIsVertexArrayOES, array);
+}
 void API_ENTRY(glGetPerfMonitorGroupsAMD)(GLint *numGroups, GLsizei groupsSize, GLuint *groups) {
     CALL_GL_API(glGetPerfMonitorGroupsAMD, numGroups, groupsSize, groups);
 }
 void API_ENTRY(glGetPerfMonitorCountersAMD)(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) {
     CALL_GL_API(glGetPerfMonitorCountersAMD, group, numCounters, maxActiveCounters, counterSize, counters);
 }
-void API_ENTRY(glGetPerfMonitorGroupStringAMD)(GLuint group, GLsizei bufSize, GLsizei *length, char *groupString) {
+void API_ENTRY(glGetPerfMonitorGroupStringAMD)(GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString) {
     CALL_GL_API(glGetPerfMonitorGroupStringAMD, group, bufSize, length, groupString);
 }
-void API_ENTRY(glGetPerfMonitorCounterStringAMD)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString) {
+void API_ENTRY(glGetPerfMonitorCounterStringAMD)(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString) {
     CALL_GL_API(glGetPerfMonitorCounterStringAMD, group, counter, bufSize, length, counterString);
 }
-void API_ENTRY(glGetPerfMonitorCounterInfoAMD)(GLuint group, GLuint counter, GLenum pname, void *data) {
+void API_ENTRY(glGetPerfMonitorCounterInfoAMD)(GLuint group, GLuint counter, GLenum pname, GLvoid *data) {
     CALL_GL_API(glGetPerfMonitorCounterInfoAMD, group, counter, pname, data);
 }
 void API_ENTRY(glGenPerfMonitorsAMD)(GLsizei n, GLuint *monitors) {
@@ -70,6 +82,21 @@
 void API_ENTRY(glGetPerfMonitorCounterDataAMD)(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) {
     CALL_GL_API(glGetPerfMonitorCounterDataAMD, monitor, pname, dataSize, data, bytesWritten);
 }
+void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
+    CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
+}
+void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
+}
+void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
+}
+void API_ENTRY(glRenderbufferStorageMultisampleIMG)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+    CALL_GL_API(glRenderbufferStorageMultisampleIMG, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glFramebufferTexture2DMultisampleIMG)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+    CALL_GL_API(glFramebufferTexture2DMultisampleIMG, target, attachment, textarget, texture, level, samples);
+}
 void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) {
     CALL_GL_API(glDeleteFencesNV, n, fences);
 }
@@ -91,10 +118,16 @@
 void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) {
     CALL_GL_API(glSetFenceNV, fence, condition);
 }
+void API_ENTRY(glCoverageMaskNV)(GLboolean mask) {
+    CALL_GL_API(glCoverageMaskNV, mask);
+}
+void API_ENTRY(glCoverageOperationNV)(GLenum operation) {
+    CALL_GL_API(glCoverageOperationNV, operation);
+}
 void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) {
     CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls);
 }
-void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString) {
+void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) {
     CALL_GL_API(glGetDriverControlStringQCOM, driverControl, bufSize, length, driverControlString);
 }
 void API_ENTRY(glEnableDriverControlQCOM)(GLuint driverControl) {
@@ -103,3 +136,45 @@
 void API_ENTRY(glDisableDriverControlQCOM)(GLuint driverControl) {
     CALL_GL_API(glDisableDriverControlQCOM, driverControl);
 }
+void API_ENTRY(glExtGetTexturesQCOM)(GLuint *textures, GLint maxTextures, GLint *numTextures) {
+    CALL_GL_API(glExtGetTexturesQCOM, textures, maxTextures, numTextures);
+}
+void API_ENTRY(glExtGetBuffersQCOM)(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) {
+    CALL_GL_API(glExtGetBuffersQCOM, buffers, maxBuffers, numBuffers);
+}
+void API_ENTRY(glExtGetRenderbuffersQCOM)(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) {
+    CALL_GL_API(glExtGetRenderbuffersQCOM, renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+void API_ENTRY(glExtGetFramebuffersQCOM)(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) {
+    CALL_GL_API(glExtGetFramebuffersQCOM, framebuffers, maxFramebuffers, numFramebuffers);
+}
+void API_ENTRY(glExtGetTexLevelParameterivQCOM)(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) {
+    CALL_GL_API(glExtGetTexLevelParameterivQCOM, texture, face, level, pname, params);
+}
+void API_ENTRY(glExtTexObjectStateOverrideiQCOM)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glExtTexObjectStateOverrideiQCOM, target, pname, param);
+}
+void API_ENTRY(glExtGetTexSubImageQCOM)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) {
+    CALL_GL_API(glExtGetTexSubImageQCOM, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+void API_ENTRY(glExtGetBufferPointervQCOM)(GLenum target, GLvoid **params) {
+    CALL_GL_API(glExtGetBufferPointervQCOM, target, params);
+}
+void API_ENTRY(glExtGetShadersQCOM)(GLuint *shaders, GLint maxShaders, GLint *numShaders) {
+    CALL_GL_API(glExtGetShadersQCOM, shaders, maxShaders, numShaders);
+}
+void API_ENTRY(glExtGetProgramsQCOM)(GLuint *programs, GLint maxPrograms, GLint *numPrograms) {
+    CALL_GL_API(glExtGetProgramsQCOM, programs, maxPrograms, numPrograms);
+}
+GLboolean API_ENTRY(glExtIsProgramBinaryQCOM)(GLuint program) {
+    CALL_GL_API_RETURN(glExtIsProgramBinaryQCOM, program);
+}
+void API_ENTRY(glExtGetProgramBinarySourceQCOM)(GLuint program, GLenum shadertype, GLchar *source, GLint *length) {
+    CALL_GL_API(glExtGetProgramBinarySourceQCOM, program, shadertype, source, length);
+}
+void API_ENTRY(glStartTilingQCOM)(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {
+    CALL_GL_API(glStartTilingQCOM, x, y, width, height, preserveMask);
+}
+void API_ENTRY(glEndTilingQCOM)(GLbitfield preserveMask) {
+    CALL_GL_API(glEndTilingQCOM, preserveMask);
+}
diff --git a/opengl/libs/GLES_CM/gl_api.in b/opengl/libs/GLES_CM/gl_api.in
index 5437d47..7f20c4f 100644
--- a/opengl/libs/GLES_CM/gl_api.in
+++ b/opengl/libs/GLES_CM/gl_api.in
@@ -259,7 +259,7 @@
 void API_ENTRY(glGetMaterialxv)(GLenum face, GLenum pname, GLfixed *params) {
     CALL_GL_API(glGetMaterialxv, face, pname, params);
 }
-void API_ENTRY(glGetPointerv)(GLenum pname, void **params) {
+void API_ENTRY(glGetPointerv)(GLenum pname, GLvoid **params) {
     CALL_GL_API(glGetPointerv, pname, params);
 }
 const GLubyte * API_ENTRY(glGetString)(GLenum name) {
diff --git a/opengl/libs/GLES_CM/glext_api.in b/opengl/libs/GLES_CM/glext_api.in
index 2c8648e..5393fa6 100644
--- a/opengl/libs/GLES_CM/glext_api.in
+++ b/opengl/libs/GLES_CM/glext_api.in
@@ -205,7 +205,7 @@
 GLboolean API_ENTRY(glUnmapBufferOES)(GLenum target) {
     CALL_GL_API_RETURN(glUnmapBufferOES, target);
 }
-void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, void** params) {
+void API_ENTRY(glGetBufferPointervOES)(GLenum target, GLenum pname, GLvoid ** params) {
     CALL_GL_API(glGetBufferPointervOES, target, pname, params);
 }
 void API_ENTRY(glCurrentPaletteMatrixOES)(GLuint matrixpaletteindex) {
@@ -268,3 +268,111 @@
 void API_ENTRY(glGetTexGenxvOES)(GLenum coord, GLenum pname, GLfixed *params) {
     CALL_GL_API(glGetTexGenxvOES, coord, pname, params);
 }
+void API_ENTRY(glBindVertexArrayOES)(GLuint array) {
+    CALL_GL_API(glBindVertexArrayOES, array);
+}
+void API_ENTRY(glDeleteVertexArraysOES)(GLsizei n, const GLuint *arrays) {
+    CALL_GL_API(glDeleteVertexArraysOES, n, arrays);
+}
+void API_ENTRY(glGenVertexArraysOES)(GLsizei n, GLuint *arrays) {
+    CALL_GL_API(glGenVertexArraysOES, n, arrays);
+}
+GLboolean API_ENTRY(glIsVertexArrayOES)(GLuint array) {
+    CALL_GL_API_RETURN(glIsVertexArrayOES, array);
+}
+void API_ENTRY(glDiscardFramebufferEXT)(GLenum target, GLsizei numAttachments, const GLenum *attachments) {
+    CALL_GL_API(glDiscardFramebufferEXT, target, numAttachments, attachments);
+}
+void API_ENTRY(glMultiDrawArraysEXT)(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawArraysEXT, mode, first, count, primcount);
+}
+void API_ENTRY(glMultiDrawElementsEXT)(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) {
+    CALL_GL_API(glMultiDrawElementsEXT, mode, count, type, indices, primcount);
+}
+void API_ENTRY(glClipPlanefIMG)(GLenum p, const GLfloat *eqn) {
+    CALL_GL_API(glClipPlanefIMG, p, eqn);
+}
+void API_ENTRY(glClipPlanexIMG)(GLenum p, const GLfixed *eqn) {
+    CALL_GL_API(glClipPlanexIMG, p, eqn);
+}
+void API_ENTRY(glRenderbufferStorageMultisampleIMG)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) {
+    CALL_GL_API(glRenderbufferStorageMultisampleIMG, target, samples, internalformat, width, height);
+}
+void API_ENTRY(glFramebufferTexture2DMultisampleIMG)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) {
+    CALL_GL_API(glFramebufferTexture2DMultisampleIMG, target, attachment, textarget, texture, level, samples);
+}
+void API_ENTRY(glDeleteFencesNV)(GLsizei n, const GLuint *fences) {
+    CALL_GL_API(glDeleteFencesNV, n, fences);
+}
+void API_ENTRY(glGenFencesNV)(GLsizei n, GLuint *fences) {
+    CALL_GL_API(glGenFencesNV, n, fences);
+}
+GLboolean API_ENTRY(glIsFenceNV)(GLuint fence) {
+    CALL_GL_API_RETURN(glIsFenceNV, fence);
+}
+GLboolean API_ENTRY(glTestFenceNV)(GLuint fence) {
+    CALL_GL_API_RETURN(glTestFenceNV, fence);
+}
+void API_ENTRY(glGetFenceivNV)(GLuint fence, GLenum pname, GLint *params) {
+    CALL_GL_API(glGetFenceivNV, fence, pname, params);
+}
+void API_ENTRY(glFinishFenceNV)(GLuint fence) {
+    CALL_GL_API(glFinishFenceNV, fence);
+}
+void API_ENTRY(glSetFenceNV)(GLuint fence, GLenum condition) {
+    CALL_GL_API(glSetFenceNV, fence, condition);
+}
+void API_ENTRY(glGetDriverControlsQCOM)(GLint *num, GLsizei size, GLuint *driverControls) {
+    CALL_GL_API(glGetDriverControlsQCOM, num, size, driverControls);
+}
+void API_ENTRY(glGetDriverControlStringQCOM)(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) {
+    CALL_GL_API(glGetDriverControlStringQCOM, driverControl, bufSize, length, driverControlString);
+}
+void API_ENTRY(glEnableDriverControlQCOM)(GLuint driverControl) {
+    CALL_GL_API(glEnableDriverControlQCOM, driverControl);
+}
+void API_ENTRY(glDisableDriverControlQCOM)(GLuint driverControl) {
+    CALL_GL_API(glDisableDriverControlQCOM, driverControl);
+}
+void API_ENTRY(glExtGetTexturesQCOM)(GLuint *textures, GLint maxTextures, GLint *numTextures) {
+    CALL_GL_API(glExtGetTexturesQCOM, textures, maxTextures, numTextures);
+}
+void API_ENTRY(glExtGetBuffersQCOM)(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) {
+    CALL_GL_API(glExtGetBuffersQCOM, buffers, maxBuffers, numBuffers);
+}
+void API_ENTRY(glExtGetRenderbuffersQCOM)(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) {
+    CALL_GL_API(glExtGetRenderbuffersQCOM, renderbuffers, maxRenderbuffers, numRenderbuffers);
+}
+void API_ENTRY(glExtGetFramebuffersQCOM)(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) {
+    CALL_GL_API(glExtGetFramebuffersQCOM, framebuffers, maxFramebuffers, numFramebuffers);
+}
+void API_ENTRY(glExtGetTexLevelParameterivQCOM)(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) {
+    CALL_GL_API(glExtGetTexLevelParameterivQCOM, texture, face, level, pname, params);
+}
+void API_ENTRY(glExtTexObjectStateOverrideiQCOM)(GLenum target, GLenum pname, GLint param) {
+    CALL_GL_API(glExtTexObjectStateOverrideiQCOM, target, pname, param);
+}
+void API_ENTRY(glExtGetTexSubImageQCOM)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) {
+    CALL_GL_API(glExtGetTexSubImageQCOM, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
+}
+void API_ENTRY(glExtGetBufferPointervQCOM)(GLenum target, GLvoid **params) {
+    CALL_GL_API(glExtGetBufferPointervQCOM, target, params);
+}
+void API_ENTRY(glExtGetShadersQCOM)(GLuint *shaders, GLint maxShaders, GLint *numShaders) {
+    CALL_GL_API(glExtGetShadersQCOM, shaders, maxShaders, numShaders);
+}
+void API_ENTRY(glExtGetProgramsQCOM)(GLuint *programs, GLint maxPrograms, GLint *numPrograms) {
+    CALL_GL_API(glExtGetProgramsQCOM, programs, maxPrograms, numPrograms);
+}
+GLboolean API_ENTRY(glExtIsProgramBinaryQCOM)(GLuint program) {
+    CALL_GL_API_RETURN(glExtIsProgramBinaryQCOM, program);
+}
+void API_ENTRY(glExtGetProgramBinarySourceQCOM)(GLuint program, GLenum shadertype, GLchar *source, GLint *length) {
+    CALL_GL_API(glExtGetProgramBinarySourceQCOM, program, shadertype, source, length);
+}
+void API_ENTRY(glStartTilingQCOM)(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) {
+    CALL_GL_API(glStartTilingQCOM, x, y, width, height, preserveMask);
+}
+void API_ENTRY(glEndTilingQCOM)(GLbitfield preserveMask) {
+    CALL_GL_API(glEndTilingQCOM, preserveMask);
+}
diff --git a/opengl/libs/egl_impl.h b/opengl/libs/egl_impl.h
index 1fba209..c8f529a 100644
--- a/opengl/libs/egl_impl.h
+++ b/opengl/libs/egl_impl.h
@@ -31,6 +31,7 @@
 
 struct egl_connection_t
 {
+    inline egl_connection_t() : dso(0) { }
     void *              dso;
     gl_hooks_t *        hooks[2];
     EGLint              major;
diff --git a/opengl/libs/entries.in b/opengl/libs/entries.in
index bbe3e23..61acb5f 100644
--- a/opengl/libs/entries.in
+++ b/opengl/libs/entries.in
@@ -4,13 +4,14 @@
 GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref)
 GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader)
 GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor)
-GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const char* name)
+GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name)
 GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer)
 GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer)
 GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer)
 GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer)
 GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer)
 GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture)
+GL_ENTRY(void, glBindVertexArrayOES, GLuint array)
 GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
 GL_ENTRY(void, glBlendEquation,  GLenum mode )
 GL_ENTRY(void, glBlendEquationOES, GLenum mode)
@@ -34,8 +35,10 @@
 GL_ENTRY(void, glClearStencil, GLint s)
 GL_ENTRY(void, glClientActiveTexture, GLenum texture)
 GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation)
+GL_ENTRY(void, glClipPlanefIMG, GLenum p, const GLfloat *eqn)
 GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation)
 GL_ENTRY(void, glClipPlanex, GLenum plane, const GLfixed *equation)
+GL_ENTRY(void, glClipPlanexIMG, GLenum p, const GLfixed *eqn)
 GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed *equation)
 GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
 GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
@@ -45,12 +48,14 @@
 GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
 GL_ENTRY(void, glCompileShader, GLuint shader)
 GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data)
-GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data)
 GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data)
-GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data)
+GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data)
 GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
 GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
 GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+GL_ENTRY(void, glCoverageMaskNV, GLboolean mask)
+GL_ENTRY(void, glCoverageOperationNV, GLenum operation)
 GL_ENTRY(GLuint, glCreateProgram, void)
 GL_ENTRY(GLuint, glCreateShader, GLenum type)
 GL_ENTRY(void, glCullFace, GLenum mode)
@@ -65,6 +70,7 @@
 GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers)
 GL_ENTRY(void, glDeleteShader, GLuint shader)
 GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures)
+GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays)
 GL_ENTRY(void, glDepthFunc, GLenum func)
 GL_ENTRY(void, glDepthMask, GLboolean flag)
 GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar)
@@ -76,6 +82,7 @@
 GL_ENTRY(void, glDisableClientState, GLenum array)
 GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl)
 GL_ENTRY(void, glDisableVertexAttribArray, GLuint index)
+GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments)
 GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count)
 GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)
 GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
@@ -93,6 +100,19 @@
 GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl)
 GL_ENTRY(void, glEnableVertexAttribArray, GLuint index)
 GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor)
+GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask)
+GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoid **params)
+GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers)
+GL_ENTRY(void, glExtGetFramebuffersQCOM, GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers)
+GL_ENTRY(void, glExtGetProgramBinarySourceQCOM, GLuint program, GLenum shadertype, GLchar *source, GLint *length)
+GL_ENTRY(void, glExtGetProgramsQCOM, GLuint *programs, GLint maxPrograms, GLint *numPrograms)
+GL_ENTRY(void, glExtGetRenderbuffersQCOM, GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers)
+GL_ENTRY(void, glExtGetShadersQCOM, GLuint *shaders, GLint maxShaders, GLint *numShaders)
+GL_ENTRY(void, glExtGetTexLevelParameterivQCOM, GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params)
+GL_ENTRY(void, glExtGetTexSubImageQCOM, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels)
+GL_ENTRY(void, glExtGetTexturesQCOM, GLuint *textures, GLint maxTextures, GLint *numTextures)
+GL_ENTRY(GLboolean, glExtIsProgramBinaryQCOM, GLuint program)
+GL_ENTRY(void, glExtTexObjectStateOverrideiQCOM, GLenum target, GLenum pname, GLint param)
 GL_ENTRY(void, glFinish, void)
 GL_ENTRY(void, glFinishFenceNV, GLuint fence)
 GL_ENTRY(void, glFlush, void)
@@ -105,6 +125,7 @@
 GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
 GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
+GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples)
 GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
 GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
 GL_ENTRY(void, glFrontFace, GLenum mode)
@@ -120,20 +141,21 @@
 GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers)
 GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers)
 GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures)
+GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays)
 GL_ENTRY(void, glGenerateMipmap, GLenum target)
 GL_ENTRY(void, glGenerateMipmapOES, GLenum target)
-GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
-GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, char* name)
+GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
+GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
 GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
-GL_ENTRY(int, glGetAttribLocation, GLuint program, const char* name)
+GL_ENTRY(int, glGetAttribLocation, GLuint program, const GLchar* name)
 GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params)
 GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params)
-GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, void** params)
+GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, GLvoid ** params)
 GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat eqn[4])
 GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat eqn[4])
 GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed eqn[4])
 GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed eqn[4])
-GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, char *driverControlString)
+GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString)
 GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls)
 GL_ENTRY(GLenum, glGetError, void)
 GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params)
@@ -150,20 +172,20 @@
 GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params)
 GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params)
 GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten)
-GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, void *data)
-GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, char *counterString)
+GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, GLvoid *data)
+GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString)
 GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters)
-GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, char *groupString)
+GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString)
 GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups)
-GL_ENTRY(void, glGetPointerv, GLenum pname, void **params)
-GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary)
-GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, char* infolog)
+GL_ENTRY(void, glGetPointerv, GLenum pname, GLvoid **params)
+GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary)
+GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
 GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params)
 GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params)
 GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params)
-GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, char* infolog)
+GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
 GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
-GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, char* source)
+GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
 GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params)
 GL_ENTRY(const GLubyte *, glGetString, GLenum name)
 GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params)
@@ -177,10 +199,10 @@
 GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params)
 GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params)
 GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params)
-GL_ENTRY(int, glGetUniformLocation, GLuint program, const char* name)
+GL_ENTRY(int, glGetUniformLocation, GLuint program, const GLchar* name)
 GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params)
 GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params)
-GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, void** pointer)
+GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer)
 GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params)
 GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params)
 GL_ENTRY(void, glHint, GLenum target, GLenum mode)
@@ -194,6 +216,7 @@
 GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer)
 GL_ENTRY(GLboolean, glIsShader, GLuint shader)
 GL_ENTRY(GLboolean, glIsTexture, GLuint texture)
+GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array)
 GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param)
 GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params)
 GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param)
@@ -228,6 +251,8 @@
 GL_ENTRY(void, glMultMatrixf, const GLfloat *m)
 GL_ENTRY(void, glMultMatrixx, const GLfixed *m)
 GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m)
+GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount)
+GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount)
 GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
 GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
 GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
@@ -254,12 +279,13 @@
 GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units)
 GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units)
 GL_ENTRY(void, glPopMatrix, void)
-GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const void *binary, GLint length)
+GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length)
 GL_ENTRY(void, glPushMatrix, void)
 GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed mantissa[16], GLint exponent[16])
 GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
 GL_ENTRY(void, glReleaseShaderCompiler, void)
 GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
 GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
 GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
 GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
@@ -274,8 +300,9 @@
 GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList)
 GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition)
 GL_ENTRY(void, glShadeModel, GLenum mode)
-GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const void* binary, GLsizei length)
-GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const char** string, const GLint* length)
+GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
+GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
+GL_ENTRY(void, glStartTilingQCOM, GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask)
 GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask)
 GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask)
 GL_ENTRY(void, glStencilMask, GLuint mask)
@@ -298,8 +325,8 @@
 GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params)
 GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param)
 GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params)
-GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat,  GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
-GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
+GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
 GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param)
 GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params)
 GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param)
@@ -309,7 +336,7 @@
 GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params)
 GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params)
 GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
-GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels)
+GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels)
 GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z)
 GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z)
 GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z)
@@ -343,7 +370,7 @@
 GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values)
 GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
 GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values)
-GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* ptr)
+GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
 GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
 GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height)
 GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h
index f47f093..1ab58cc 100644
--- a/opengl/libs/hooks.h
+++ b/opengl/libs/hooks.h
@@ -37,7 +37,7 @@
 #endif
 #undef NELEM
 #define NELEM(x)                    (sizeof(x)/sizeof(*(x)))
-#define MAX_NUMBER_OF_GL_EXTENSIONS 32
+#define MAX_NUMBER_OF_GL_EXTENSIONS 64
 
 
 #if defined(HAVE_ANDROID_OS) && !USE_SLOW_BINDING && __OPTIMIZE__
@@ -86,7 +86,7 @@
         #include "entries.in"
     } gl;
     struct gl_ext_t {
-        void (*extensions[MAX_NUMBER_OF_GL_EXTENSIONS])(void);
+        __eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];
     } ext;
 };
 #undef GL_ENTRY
diff --git a/opengl/tests/angeles/app-linux.cpp b/opengl/tests/angeles/app-linux.cpp
index 06fa0c2..4d10ee5 100644
--- a/opengl/tests/angeles/app-linux.cpp
+++ b/opengl/tests/angeles/app-linux.cpp
@@ -63,7 +63,7 @@
 int gAppAlive = 1;
 
 static const char sAppName[] =
-    "San Angeles Observation OpenGL ES version example (Linux)";
+        "San Angeles Observation OpenGL ES version example (Linux)";
 
 static int sWindowWidth = WINDOW_DEFAULT_WIDTH;
 static int sWindowHeight = WINDOW_DEFAULT_HEIGHT;
@@ -74,22 +74,22 @@
 const char *egl_strerror(unsigned err)
 {
     switch(err){
-    case EGL_SUCCESS: return "SUCCESS";
-    case EGL_NOT_INITIALIZED: return "NOT INITIALIZED";
-    case EGL_BAD_ACCESS: return "BAD ACCESS";
-    case EGL_BAD_ALLOC: return "BAD ALLOC";
-    case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE";
-    case EGL_BAD_CONFIG: return "BAD CONFIG";
-    case EGL_BAD_CONTEXT: return "BAD CONTEXT";
-    case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE";
-    case EGL_BAD_DISPLAY: return "BAD DISPLAY";
-    case EGL_BAD_MATCH: return "BAD MATCH";
-    case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP";
-    case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW";
-    case EGL_BAD_PARAMETER: return "BAD PARAMETER";
-    case EGL_BAD_SURFACE: return "BAD_SURFACE";
-//    case EGL_CONTEXT_LOST: return "CONTEXT LOST";
-    default: return "UNKNOWN";
+        case EGL_SUCCESS: return "SUCCESS";
+        case EGL_NOT_INITIALIZED: return "NOT INITIALIZED";
+        case EGL_BAD_ACCESS: return "BAD ACCESS";
+        case EGL_BAD_ALLOC: return "BAD ALLOC";
+        case EGL_BAD_ATTRIBUTE: return "BAD_ATTRIBUTE";
+        case EGL_BAD_CONFIG: return "BAD CONFIG";
+        case EGL_BAD_CONTEXT: return "BAD CONTEXT";
+        case EGL_BAD_CURRENT_SURFACE: return "BAD CURRENT SURFACE";
+        case EGL_BAD_DISPLAY: return "BAD DISPLAY";
+        case EGL_BAD_MATCH: return "BAD MATCH";
+        case EGL_BAD_NATIVE_PIXMAP: return "BAD NATIVE PIXMAP";
+        case EGL_BAD_NATIVE_WINDOW: return "BAD NATIVE WINDOW";
+        case EGL_BAD_PARAMETER: return "BAD PARAMETER";
+        case EGL_BAD_SURFACE: return "BAD_SURFACE";
+        //    case EGL_CONTEXT_LOST: return "CONTEXT LOST";
+        default: return "UNKNOWN";
     }
 }
 
@@ -118,52 +118,59 @@
         fprintf(stderr, "EGL Error: 0x%04x\n", (int)error);
 }
 
-static int initGraphics()
+static int initGraphics(unsigned samples)
 {
     EGLint configAttribs[] = {
-         EGL_DEPTH_SIZE, 16,
-         EGL_NONE
-     };
-     
-     EGLint majorVersion;
-     EGLint minorVersion;
-     EGLContext context;
-     EGLConfig config;
-     EGLSurface surface;
-     EGLint w, h;
-     EGLDisplay dpy;
+            EGL_DEPTH_SIZE, 16,
+            EGL_SAMPLE_BUFFERS, samples ? 1 : 0,
+                    EGL_SAMPLES, samples,
+                    EGL_NONE
+    };
 
-     EGLNativeWindowType window = android_createDisplaySurface();
-     
-     dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-     eglInitialize(dpy, &majorVersion, &minorVersion);
-          
-     status_t err = EGLUtils::selectConfigForNativeWindow(
-             dpy, configAttribs, window, &config);
-     if (err) {
-         fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
-         return 0;
-     }
+    EGLint majorVersion;
+    EGLint minorVersion;
+    EGLContext context;
+    EGLConfig config;
+    EGLSurface surface;
+    EGLint w, h;
+    EGLDisplay dpy;
 
-     surface = eglCreateWindowSurface(dpy, config, window, NULL);
-     egl_error("eglCreateWindowSurface");
+    EGLNativeWindowType window = android_createDisplaySurface();
 
-     fprintf(stderr,"surface = %p\n", surface);
+    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    eglInitialize(dpy, &majorVersion, &minorVersion);
 
-     context = eglCreateContext(dpy, config, NULL, NULL);
-     egl_error("eglCreateContext");
-     fprintf(stderr,"context = %p\n", context);
-     
-     eglMakeCurrent(dpy, surface, surface, context);   
-     egl_error("eglMakeCurrent");
+    status_t err = EGLUtils::selectConfigForNativeWindow(
+            dpy, configAttribs, window, &config);
+    if (err) {
+        fprintf(stderr, "couldn't find an EGLConfig matching the screen format\n");
+        return 0;
+    }
 
-     eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth);
-     eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight);
+    surface = eglCreateWindowSurface(dpy, config, window, NULL);
+    egl_error("eglCreateWindowSurface");
+
+    fprintf(stderr,"surface = %p\n", surface);
+
+    context = eglCreateContext(dpy, config, NULL, NULL);
+    egl_error("eglCreateContext");
+    fprintf(stderr,"context = %p\n", context);
+
+    eglMakeCurrent(dpy, surface, surface, context);
+    egl_error("eglMakeCurrent");
+
+    eglQuerySurface(dpy, surface, EGL_WIDTH, &sWindowWidth);
+    eglQuerySurface(dpy, surface, EGL_HEIGHT, &sWindowHeight);
 
     sEglDisplay = dpy;
     sEglSurface = surface;
     sEglContext = context;
 
+    if (samples == 0) {
+        // GL_MULTISAMPLE is enabled by default
+        glDisable(GL_MULTISAMPLE);
+    }
+
     return EGL_TRUE;
 }
 
@@ -179,35 +186,47 @@
 
 int main(int argc, char *argv[])
 {
-    // not referenced:
-    argc = argc;
-    argv = argv;
+    unsigned samples = 0;
+    printf("usage: %s [samples]\n", argv[0]);
+    if (argc == 2) {
+        samples = atoi( argv[1] );
+        printf("Multisample enabled: GL_SAMPLES = %u\n", samples);
+    }
 
-    if (!initGraphics())
+    if (!initGraphics(samples))
     {
         fprintf(stderr, "Graphics initialization failed.\n");
         return EXIT_FAILURE;
     }
 
     appInit();
-    
+
+    struct timeval timeTemp;
+    int frameCount = 0;
+    gettimeofday(&timeTemp, NULL);
+    double totalTime = timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec;
+
     while (gAppAlive)
     {
         struct timeval timeNow;
 
-        if (gAppAlive)
-        {
-            gettimeofday(&timeNow, NULL);
-            appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000,
-                      sWindowWidth, sWindowHeight);
-            checkGLErrors();
-            eglSwapBuffers(sEglDisplay, sEglSurface);
-            checkEGLErrors();
-        }
+        gettimeofday(&timeNow, NULL);
+        appRender(timeNow.tv_sec * 1000 + timeNow.tv_usec / 1000,
+                sWindowWidth, sWindowHeight);
+        checkGLErrors();
+        eglSwapBuffers(sEglDisplay, sEglSurface);
+        checkEGLErrors();
+        frameCount++;
     }
 
+    gettimeofday(&timeTemp, NULL);
+
     appDeinit();
     deinitGraphics();
 
+    totalTime = (timeTemp.tv_usec/1000000.0 + timeTemp.tv_sec) - totalTime;
+    printf("totalTime=%f s, frameCount=%d, %.2f fps\n",
+            totalTime, frameCount, frameCount/totalTime);
+
     return EXIT_SUCCESS;
 }
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index 2361db5..f274c7c 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -195,7 +195,6 @@
     X(EGL_NATIVE_RENDERABLE),
     X(EGL_NATIVE_VISUAL_ID),
     X(EGL_NATIVE_VISUAL_TYPE),
-    X(EGL_PRESERVED_RESOURCES),
     X(EGL_SAMPLES),
     X(EGL_SAMPLE_BUFFERS),
     X(EGL_SURFACE_TYPE),
diff --git a/opengl/tests/gl_basic/gl_basic.cpp b/opengl/tests/gl_basic/gl_basic.cpp
index feb964a..0cc8398 100644
--- a/opengl/tests/gl_basic/gl_basic.cpp
+++ b/opengl/tests/gl_basic/gl_basic.cpp
@@ -114,7 +114,6 @@
     X(EGL_NATIVE_RENDERABLE),
     X(EGL_NATIVE_VISUAL_ID),
     X(EGL_NATIVE_VISUAL_TYPE),
-    X(EGL_PRESERVED_RESOURCES),
     X(EGL_SAMPLES),
     X(EGL_SAMPLE_BUFFERS),
     X(EGL_SURFACE_TYPE),
diff --git a/opengl/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..a14bfb5
--- /dev/null
+++ b/services/surfaceflinger/Android.mk
@@ -0,0 +1,52 @@
+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
+
+# 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..0515110
--- /dev/null
+++ b/services/surfaceflinger/DisplayHardware/DisplayHardware.cpp
@@ -0,0 +1,340 @@
+/*
+ * 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
+     */
+    
+    context = eglCreateContext(display, config, NULL, NULL);
+    
+    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/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
similarity index 100%
rename from libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
rename to services/surfaceflinger/DisplayHardware/DisplayHardwareBase.cpp
diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h b/services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
similarity index 100%
rename from libs/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
rename to services/surfaceflinger/DisplayHardware/DisplayHardwareBase.h
diff --git a/services/surfaceflinger/GLExtensions.cpp b/services/surfaceflinger/GLExtensions.cpp
new file mode 100644
index 0000000..850866a
--- /dev/null
+++ b/services/surfaceflinger/GLExtensions.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#include "GLExtensions.h"
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+ANDROID_SINGLETON_STATIC_INSTANCE( GLExtensions )
+
+GLExtensions::GLExtensions()
+    : mHaveTextureExternal(false),
+      mHaveNpot(false),
+      mHaveDirectTexture(false)
+{
+}
+
+void GLExtensions::initWithGLStrings(
+        GLubyte const* vendor,
+        GLubyte const* renderer,
+        GLubyte const* version,
+        GLubyte const* extensions,
+        char const* egl_vendor,
+        char const* egl_version,
+        char const* egl_extensions)
+{
+    mVendor     = (char const*)vendor;
+    mRenderer   = (char const*)renderer;
+    mVersion    = (char const*)version;
+    mExtensions = (char const*)extensions;
+    mEglVendor     = egl_vendor;
+    mEglVersion    = egl_version;
+    mEglExtensions = egl_extensions;
+
+    char const* curr = (char const*)extensions;
+    char const* head = curr;
+    do {
+        head = strchr(curr, ' ');
+        String8 s(curr, head ? head-curr : strlen(curr));
+        if (s.length()) {
+            mExtensionList.add(s);
+        }
+        curr = head+1;
+    } while (head);
+
+    curr = egl_extensions;
+    head = curr;
+    do {
+        head = strchr(curr, ' ');
+        String8 s(curr, head ? head-curr : strlen(curr));
+        if (s.length()) {
+            mExtensionList.add(s);
+        }
+        curr = head+1;
+    } while (head);
+
+#ifdef EGL_ANDROID_image_native_buffer
+    if (hasExtension("GL_OES_EGL_image") &&
+        (hasExtension("EGL_KHR_image_base") || hasExtension("EGL_KHR_image")) &&
+        hasExtension("EGL_ANDROID_image_native_buffer"))
+    {
+        mHaveDirectTexture = true;
+    }
+#else
+#warning "EGL_ANDROID_image_native_buffer not supported"
+#endif
+
+    if (hasExtension("GL_ARB_texture_non_power_of_two")) {
+        mHaveNpot = true;
+    }
+
+    if (hasExtension("GL_OES_EGL_image_external")) {
+        mHaveTextureExternal = true;
+    } else if (strstr(mRenderer.string(), "Adreno")) {
+        // hack for Adreno 200
+        mHaveTextureExternal = true;
+    }
+}
+
+bool GLExtensions::hasExtension(char const* extension) const
+{
+    const String8 s(extension);
+    return mExtensionList.indexOf(s) >= 0;
+}
+
+char const* GLExtensions::getVendor() const {
+    return mVendor.string();
+}
+
+char const* GLExtensions::getRenderer() const {
+    return mRenderer.string();
+}
+
+char const* GLExtensions::getVersion() const {
+    return mVersion.string();
+}
+
+char const* GLExtensions::getExtension() const {
+    return mExtensions.string();
+}
+
+char const* GLExtensions::getEglVendor() const {
+    return mEglVendor.string();
+}
+
+char const* GLExtensions::getEglVersion() const {
+    return mEglVersion.string();
+}
+
+char const* GLExtensions::getEglExtension() const {
+    return mEglExtensions.string();
+}
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
diff --git a/services/surfaceflinger/GLExtensions.h b/services/surfaceflinger/GLExtensions.h
new file mode 100644
index 0000000..bbb284e
--- /dev/null
+++ b/services/surfaceflinger/GLExtensions.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SF_GLEXTENSION_H
+#define ANDROID_SF_GLEXTENSION_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/String8.h>
+#include <utils/SortedVector.h>
+#include <utils/Singleton.h>
+
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+class GLExtensions : public Singleton<GLExtensions>
+{
+    friend class Singleton<GLExtensions>;
+
+    bool mHaveTextureExternal   : 1;
+    bool mHaveNpot              : 1;
+    bool mHaveDirectTexture     : 1;
+
+    String8 mVendor;
+    String8 mRenderer;
+    String8 mVersion;
+    String8 mExtensions;
+    String8 mEglVendor;
+    String8 mEglVersion;
+    String8 mEglExtensions;
+    SortedVector<String8> mExtensionList;
+
+    GLExtensions(const GLExtensions&);
+    GLExtensions& operator = (const GLExtensions&);
+
+protected:
+    GLExtensions();
+
+public:
+    inline bool haveTextureExternal() const {
+        return mHaveTextureExternal;
+    }
+    inline bool haveNpot() const {
+        return mHaveNpot;
+    }
+    inline bool haveDirectTexture() const {
+        return mHaveDirectTexture;
+    }
+
+    void initWithGLStrings(
+            GLubyte const* vendor,
+            GLubyte const* renderer,
+            GLubyte const* version,
+            GLubyte const* extensions,
+            char const* egl_vendor,
+            char const* egl_version,
+            char const* egl_extensions);
+
+    char const* getVendor() const;
+    char const* getRenderer() const;
+    char const* getVersion() const;
+    char const* getExtension() const;
+
+    char const* getEglVendor() const;
+    char const* getEglVersion() const;
+    char const* getEglExtension() const;
+
+    bool hasExtension(char const* extension) const;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_SF_GLEXTENSION_H
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
new file mode 100644
index 0000000..695cbfa
--- /dev/null
+++ b/services/surfaceflinger/Layer.cpp
@@ -0,0 +1,880 @@
+/*
+ * 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::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..e1d283b
--- /dev/null
+++ b/services/surfaceflinger/Layer.h
@@ -0,0 +1,239 @@
+/*
+ * 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 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..6fc5010
--- /dev/null
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -0,0 +1,639 @@
+/*
+ * 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::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);
+    }
+
+    struct TexCoords {
+        GLfloat u;
+        GLfloat v;
+    };
+
+    enum {
+        // name of the corners in the texture map
+        LB = 0, // left-bottom
+        LT = 1, // left-top
+        RT = 2, // right-top
+        RB = 3  // right-bottom
+    };
+
+    // vertices in screen space
+    int vLT = LB;
+    int vLB = LT;
+    int vRB = RT;
+    int vRT = RB;
+
+    // the texture's source is rotated
+    uint32_t transform = mBufferTransform;
+    if (transform & HAL_TRANSFORM_ROT_90) {
+        vLT = RB;
+        vLB = LB;
+        vRB = LT;
+        vRT = RT;
+    }
+    if (transform & HAL_TRANSFORM_FLIP_V) {
+        swap(vLT, vLB);
+        swap(vRB, vRT);
+    }
+    if (transform & HAL_TRANSFORM_FLIP_H) {
+        swap(vLT, vRB);
+        swap(vLB, vRT);
+    }
+
+    TexCoords texCoords[4];
+    texCoords[vLT].u = cl;
+    texCoords[vLT].v = ct;
+    texCoords[vLB].u = cl;
+    texCoords[vLB].v = cb;
+    texCoords[vRB].u = cr;
+    texCoords[vRB].v = cb;
+    texCoords[vRT].u = cr;
+    texCoords[vRT].v = ct;
+
+    if (needsDithering()) {
+        glEnable(GL_DITHER);
+    } else {
+        glDisable(GL_DITHER);
+    }
+
+    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+    glVertexPointer(2, GL_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..8cba287
--- /dev/null
+++ b/services/surfaceflinger/LayerBase.h
@@ -0,0 +1,338 @@
+/*
+ * 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;
+    
+    /**
+     * 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..0240748
--- /dev/null
+++ b/services/surfaceflinger/LayerBuffer.cpp
@@ -0,0 +1,682 @@
+/*
+ * 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::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::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/services/surfaceflinger/LayerBuffer.h b/services/surfaceflinger/LayerBuffer.h
new file mode 100644
index 0000000..1c0bf83
--- /dev/null
+++ b/services/surfaceflinger/LayerBuffer.h
@@ -0,0 +1,220 @@
+/*
+ * 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 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 uint32_t doTransaction(uint32_t flags);
+    virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
+
+    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 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..d668e88
--- /dev/null
+++ b/services/surfaceflinger/MessageQueue.cpp
@@ -0,0 +1,193 @@
+/*
+ * 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;
+
+            // 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->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..dc241d4
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -0,0 +1,1837 @@
+/*
+ * 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"),
+        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<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();
+    }
+
+    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;
+
+    /*
+     * 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:
+        {
+            // 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
+            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;
+}
+
+// ---------------------------------------------------------------------------
+
+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;
+}
+
+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..8ecfc01
--- /dev/null
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -0,0 +1,420 @@
+/*
+ * 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;
+        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;
+
+            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();
+
+
+            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                  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;
+                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..5e27cc9
--- /dev/null
+++ b/services/surfaceflinger/Transform.cpp
@@ -0,0 +1,391 @@
+/*
+ * 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(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_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/services/surfaceflinger/Transform.h b/services/surfaceflinger/Transform.h
new file mode 100644
index 0000000..20fa11a
--- /dev/null
+++ b/services/surfaceflinger/Transform.h
@@ -0,0 +1,126 @@
+/*
+ * 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();
+
+            // 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(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/surface/Android.mk b/services/surfaceflinger/tests/surface/Android.mk
new file mode 100644
index 0000000..ce0e807
--- /dev/null
+++ b/services/surfaceflinger/tests/surface/Android.mk
@@ -0,0 +1,18 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	surface.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+    libui \
+    libsurfaceflinger_client
+
+LOCAL_MODULE:= test-surface
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
new file mode 100644
index 0000000..b4de4b4
--- /dev/null
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -0,0 +1,54 @@
+#include <cutils/memory.h>
+
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <ui/Overlay.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+    // set up the thread-pool
+    sp<ProcessState> proc(ProcessState::self());
+    ProcessState::self()->startThreadPool();
+
+    // create a client to surfaceflinger
+    sp<SurfaceComposerClient> client = new SurfaceComposerClient();
+    
+    // create pushbuffer surface
+    sp<SurfaceControl> surfaceControl = client->createSurface(
+            getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565);
+    client->openTransaction();
+    surfaceControl->setLayer(100000);
+    client->closeTransaction();
+
+    // pretend it went cross-process
+    Parcel parcel;
+    SurfaceControl::writeSurfaceToParcel(surfaceControl, &parcel);
+    parcel.setDataPosition(0);
+    sp<Surface> surface = Surface::readFromParcel(parcel);
+    ANativeWindow* window = surface.get();
+
+    printf("window=%p\n", window);
+
+    int err = native_window_set_buffer_count(window, 8);
+    android_native_buffer_t* buffer;
+
+    for (int i=0 ; i<8 ; i++) {
+        window->dequeueBuffer(window, &buffer);
+        printf("buffer %d: %p\n", i, buffer);
+    }
+
+    printf("test complete. CTRL+C to finish.\n");
+
+    IPCThreadState::self()->joinThreadPool();
+    return 0;
+}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce522c8..ce40b5d 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -85,7 +85,8 @@
 
     // TODO(oam): Test VPN when EFS is enabled (will do later)...
     public static String getProfilePath() {
-        return Environment.getDataDirectory().getPath() + PROFILES_PATH;
+        // This call will return the correct path if Encrypted FS is enabled or not.
+        return Environment.getSecureDataDirectory().getPath() + PROFILES_PATH;
     }
 
     /**
